Compare commits

...
76 Commits
Author SHA1 Message Date
imhao183 069770c411 version 0.42 -> 0.43 2020-08-01 18:54:55 +08:00
imhao183 1f5f7eb572 修正推送数据中unread message count不准确的问题 2020-08-01 09:25:24 +08:00
imhao183 405ad6c121 fix build error 2020-07-27 16:10:58 +08:00
imhao183 ff6e94cee7 remove useless errorcode 2020-07-22 11:53:15 +08:00
imhao183 db6f273cba fix build error 2020-07-21 22:13:11 +08:00
imhao183 df3bace44b 创建群组时添加更多的参数 2020-07-21 22:07:50 +08:00
heavyrain.lee 3f9a8be02c Update ISSUE_TEMPLATE.md 2020-07-17 12:03:42 +08:00
imhao183 39eb08e3f2 消息过期错误修改 2020-07-16 17:55:34 +08:00
imhao183 22a4ef4f42 修正撤回消息时异常信息问题 2020-07-16 15:22:21 +08:00
imhao183 da0d2e22cc message content add push attribute 2020-07-15 08:15:54 +08:00
imhao183 a80ef20da3 message content add push data attribute 2020-07-15 08:12:00 +08:00
imhao183 45fd11f641 修正黑名单问题 2020-07-13 21:21:37 +08:00
imhao183 cdc731a23b update 2020-07-10 11:34:32 +08:00
imhao183 68a968a94c 避免数据库表中的列名与某些数据库关键字冲突 2020-07-09 16:48:45 +08:00
imhao183 8604f4edf3 添加注释 2020-07-09 16:48:15 +08:00
imndx b1484b0c95 fix recall message issue 2020-07-06 16:02:11 +08:00
imhao183 631986f7a2 更新说明 2020-07-06 12:36:28 +08:00
imhao183 db27e77303 添加说明 2020-07-03 20:47:44 +08:00
imhao183 5177779066 fix server api group operation failure issue 2020-07-01 14:20:04 +08:00
imhao183 c4a764d81d update 2020-07-01 11:22:20 +08:00
imhao183 2c5ae2bd86 update version to 0.42 2020-07-01 11:04:42 +08:00
imhao183 b11d609ea0 update 2020-07-01 11:04:10 +08:00
imhao183 b8170c4757 修改好友欢迎提示方式,默认为关,需要在客户端上实现后打开 2020-06-30 17:15:53 +08:00
imhao183 e42d6f8e4f fix sql error 2020-06-25 16:07:49 +08:00
imhao183 e0c95bace9 数据库group表添加2个字段 2020-06-25 16:00:08 +08:00
imhao183 8623223991 添加群成员时,检查系统群最大成员数 2020-06-24 11:57:15 +08:00
heavyrain.lee efdcc24067 Update README.md 2020-06-24 09:26:46 +08:00
imhao183 ec18e40eb0 normal 类型的群组群成员可以修改群名称头像和extra,群主和群管理可以修改所有信息 2020-06-22 21:50:17 +08:00
heavyrain2012 f9d970c730 server api 发送接口添加extra字段 2020-06-18 17:22:45 +08:00
imhao183 590b02cc8e session修改成同步操作 2020-06-16 17:01:59 +08:00
imhao183 f2f75d3048 计数问题修正 2020-06-12 07:54:28 +08:00
imhao183 94466139f6 群成员增加加入时间字段 2020-06-11 20:58:24 +08:00
imhao183 70aeff9ac5 更新协议,在群成员数据结构中添加创建时间属性 2020-06-11 15:47:40 +08:00
imndx 7e56fe2ee0 参数校验 2020-06-09 17:11:48 +08:00
imndx 599547d627 修复黑名单问题. fix #213, fix #212 2020-06-09 16:53:24 +08:00
imhao183 28600ea7f9 修正文件名中带有&字符错误问题 2020-06-08 21:43:12 +08:00
heavyrain2012 a73507c673 解决群组通知line错误问题 2020-06-08 19:10:13 +08:00
imhao183 84b8d4cd09 fix build error 2020-06-04 07:47:11 +08:00
imhao183 b66aa3d634 消息转发时带上消息ID和时间戳 2020-06-04 07:44:11 +08:00
imhao183 508beaf62c SDK增加群内成员禁言功能 2020-05-24 19:02:39 +08:00
imhao183 e914afedf4 同步专业版数据库 2020-05-23 17:25:52 +08:00
heavyrain.lee 49c32d7fa1 Update README.md 2020-05-20 07:02:32 +08:00
imhao183 aac106d37e 更新注释 2020-05-15 09:51:31 +08:00
imhao183 8bd17a8093 更新注释 2020-05-13 19:16:15 +08:00
imhao183 b1f07f49ff api接口获取群成员信息时,过滤掉已删除成员 2020-05-11 12:12:51 +08:00
imhao183 86dddfd85f fix build error 2020-05-11 08:33:09 +08:00
imhao183 db733efc44 解决SDK中修改群信息的接口缺少自定义消息的问题 2020-05-06 21:00:41 +08:00
imhao183 69f28bd35b 当接受好友邀请时,如果已经是好友,返回“已经是好友”的错误码 2020-05-06 20:50:15 +08:00
heavyrain2012 4179788899 update version to 0.41 2020-05-05 19:29:03 +08:00
imhao183 1654baa523 添加服务器端删除消息的api 2020-05-03 13:38:18 +08:00
heavyrain2012 2163b9d580 remove useless code 2020-05-02 08:15:11 +08:00
heavyrain2012 8bec058e20 add ignore 2020-05-02 08:15:03 +08:00
imhao183 4aa2001f7b api 2020-05-01 12:39:40 +08:00
imhao183 c741b4e1da things api and db 2020-05-01 12:39:29 +08:00
imhao183 e771794bc0 things db config and sdk 2020-05-01 12:38:27 +08:00
imhao183 739452830d 用户退出时,多加一种选择,停用session不清除session 2020-04-28 07:40:55 +08:00
heavyrain.lee 16deebb565 添加是否禁止服务器端保存searchable_content字段的配置 2020-04-25 20:43:20 +08:00
heavyrain.lee 4411a75535 fix build error 2020-04-24 12:10:09 +08:00
heavyrain.lee 93bb9b50ae 添加PC下线功能 2020-04-24 12:08:17 +08:00
imhao183 1f45372b24 Revert "update"
This reverts commit 5ec14502f8.
2020-04-23 18:44:45 +08:00
imhao183 5ec14502f8 update 2020-04-22 08:05:36 +08:00
heavyrain.lee 7c0666e13c update sql 2020-04-18 20:38:36 +08:00
heavyrain.lee 42d0a5334e add sql 2020-04-18 20:28:37 +08:00
heavyrain.lee 8a4ae37247 update version to 0.40 2020-04-15 10:52:33 +08:00
heavyrain.lee c11b004e04 update 2020-04-15 10:34:33 +08:00
imhao183 4d07757b83 添加sticker/moments的bucket支持 2020-04-14 16:12:19 +08:00
heavyrain.lee bdc2f70785 update 2020-04-11 08:13:32 +08:00
imhao183 768fe75e04 update sdk to fix black list api 2020-04-08 16:13:21 +08:00
heavyrain.lee 2ba54a41db 撤回消息时带上被撤回消息的信息 2020-04-06 11:29:31 +08:00
imhao183 e414fa4a0a fix error 2020-04-05 22:48:28 +08:00
imhao183 da011f4957 添加PC在线状态通知开关 2020-04-05 21:14:39 +08:00
heavyrain.lee 38f42697cb upgrade mysql connector to 8.0.19 2020-04-05 12:11:56 +08:00
imhao183 3f5a8f579a 添加禁止好友请求的配置。另外更新部分配置说明 2020-04-04 10:11:42 +08:00
imhao183 5ebd77a1a1 添加禁止搜索用户和禁止昵称搜索用户的配置项 2020-04-04 09:55:53 +08:00
imhao183 1047db9990 add chatroom api 2020-04-02 22:50:04 +08:00
imhao183 83eae385b3 修改拒绝好友请求的错误 2020-04-02 18:26:15 +08:00
90 changed files with 2531 additions and 2187 deletions
+12 -8
View File
@@ -1,13 +1,17 @@
### Expected behavior
## 提issue小提示
为了尽快定位问题,需要提供足够的信息,请按照我们的要求格式来提问。***如果您不按照格式提问,我们将无法回复您的问题***
### Actual behavior
#### 操作说明
详细说明操作那个界面,每一步骤都要说得详细,如果是SDK或者api使用问题,需要详细说明调用的那个函数,参数都是什么。
### Steps to reproduce
#### 表现现象
描述一下什么现象,比如说函数返回error,errorcode是多少,或者界面上是什么状态,比如发送消息显示发送失败的红点。不要笼统的说功能有问题,不起作用。
### Minimal yet complete reproducer code (or URL to code) or complete log file
#### 预期结果
你认为正确的表现应该是什么样的。
### Moquette MQTT version
#### 补充条件
是否是毕现的,还是偶现的?是否只有在特殊的网络/设备/平台上出现,还是所有的都出现。还有您用的版本是什么时候的,是不是最新版
### JVM version (e.g. `java -version`)
### OS version (e.g. `uname -a`)
#### demo对比结果
请用demo对比测试,demo上是什么状态。
+2
View File
@@ -60,3 +60,5 @@ moments/target
monitor
wildfire_jmeter
git.properties
wildfirechat.license
broker/logs
+3 -9
View File
@@ -43,11 +43,6 @@
![野火IM](http://static.wildfirechat.cn/download_qrcode.png)
#### 加入野火官方体验交流群
使用野火IM移动客户端扫码下面二维码(不是使用微信扫码),和野火IM的爱好者一起畅谈野火IM的问题和经验:
![野火IM官方交流群](http://static.wildfirechat.cn/wildfirechat_official_group.jpeg)
#### 应用截图
![ios-demo](http://static.wildfirechat.cn/ios-demo.gif)
@@ -73,12 +68,11 @@
## 编译
在安装JDK1.8以上及maven的前提下,在命令行中执行```mvn clean compile package```,生成的目标文件在```./distribution/target/distribution-xxxx-bundle-tar.tar.gz```
> 由于使用了一个git的maven插件,如果本地没有git信息就会编译出错,请使用```git clone```的方法下载代码,或者下载压缩包解压后在根目录创建```.git```的空目录。建议用```git clone```的方式下载代码。
## 捐赠者名单
## 升级说明
1. 从0.42 版本增加了群成员数限制,默认为2000。如果您从之前的版本升级到这个版本或以后,需要注意到群成员数的限制。升级之后超出限制的群不受影响,但不能继续加人,如果您想修改默认值,可以在升级版本之后,修改t_setting表,把默认的大小改为您期望的人数。另外修改t_group表,把已经存在的群组max_member_count改成您期望的,然后重启。
| 捐赠者 | 商标 | 金额 | 简介 |
| ----- | ---- | -------- | --- |
| [SAMOS](http://samos.io) | ![SAMOS](http://static.wildfirechat.cn/SAMOS.png) | 保密 | 一站式区块链解决方案服务商(http://samos.io) |
## 特别感谢
1. [moquette](https://github.com/moquette-io/moquette) 本项目是基于此项目二次开发而来,处理MQTT相关业务。
+18 -3
View File
@@ -90,6 +90,12 @@
<map name="user_chatroom">
</map>
<multimap name="chatroom_black">
</multimap>
<multimap name="chatroom_manager">
</multimap>
<map name="robots">
<!-- 7 days -->
<time-to-live-seconds>604800</time-to-live-seconds>
@@ -101,14 +107,23 @@
<write-delay-seconds>0</write-delay-seconds>
</map-store>
</map>
<map name="things">
<map name="devices">
<!-- 7 days -->
<time-to-live-seconds>604800</time-to-live-seconds>
<eviction-policy>LRU</eviction-policy>
<max-size policy="PER_NODE">1000000</max-size>
<eviction-percentage>10</eviction-percentage>
<map-store enabled="true">
<class-name>io.moquette.persistence.DeviceLoader</class-name>
<write-delay-seconds>0</write-delay-seconds>
</map-store>
</map>
<multimap name="user_robots">
</multimap>
<multimap name="user_things">
<multimap name="user_devices">
</multimap>
<multimap name="chatroom_members">
+37 -5
View File
@@ -55,10 +55,12 @@ token.key testim
##token的过期时间,单位为毫秒,默认为无限期。如果需要设置无限期,客户端上一定需要加上token过期的处理。token过期的处理请参考文档的常见问题
##token.expire_time 2592000000
##首次登录,是否接收之前的历史消息。0 不接收;1接收。
##首次登录,是否接收之前的历史消息。
##0 不接收历史消息,只接收5分钟以内的消息,由于服务器没有保存已经收取记录,所以如果有超过5分钟之前未收取的消息也不会收取下拉;
##1接收,会接收 message.max_queue 配置的条数的历史消息
message.roaming 0
##是否开启拉取远程历史消息
##是否开启拉取远程历史消息。如果为1,客户端在会话内如果本地消息读取完了,可以下拉继续加载在服务器上的该会话的消息;如果为0则不能。
message.remote_history_message 0
##服务器为每个用户缓存的消息数量。这个值改得太大,拉取消息时间变长,另外会占用大量内存。
@@ -67,10 +69,22 @@ message.max_queue 1024
##是否禁止陌生人聊天
message.disable_stranger_chat false
##黑名单处理策略,0 发送失败,返回被拉黑的错误码;1 发送成功但消息被服务器直接丢弃;
##黑名单处理策略,0 发送失败,返回被拉黑的错误码;1 发送成功但消息被服务器直接丢弃;2 敏感词替换为***;3 不处理。
##所有命中敏感词的消息都会被记录在敏感词消息表中
message.blacklist.strategy 0
##是否禁止服务器端消息搜索,该功能暂未实现。目前的影响是如果打开,则存储消息时不单独保存_searchable_content字段
message.disable_remote_search false
##禁止搜索用户
friend.disable_search false
##禁止按照昵称搜索用户。
friend.disable_nick_name_search false
##禁止发送好友邀请,通过server api添加好友不受此限制
friend.disable_friend_request false
##好友请求重复发送的间隔,单位是毫秒,默认是7天,0为不限制
friend.repeat_request_duration 604800000
@@ -80,6 +94,12 @@ friend.reject_request_duration 2592000000
##好友请求过期时间,单位是毫秒,默认是7天,0为不限制
friend.request_expiration_duration 604800000
##添加好友后会发送欢迎消息,比如"你们已经是好友了,可以聊天了"。这个开关控制是用旧的方式还是用新的方式。
##旧的方式会发送notification消息(contenttype是80),内容会根据好友接收者的语言选择对应的语言,如果双方语言不一致会导致另外一方看到的不是本地语言。
##新的方式会发送添加好友消息(contenttype是93)和欢迎消息(contenttype是92),需要客户端实现这两种消息。
##如果客户端已经实现这两种消息可以打开这个开关
friend.new_welcome_message false
## 聊天室观众空闲退出时间,单位为毫秒,默认为15分钟,0为永远不退出
chatroom.participant_idle_time 900000
@@ -120,6 +140,10 @@ qiniu.bucket_video_name media
qiniu.bucket_video_domain http://pghnpyzos.bkt.clouddn.com
qiniu.bucket_file_name media
qiniu.bucket_file_domain http://pghnpyzos.bkt.clouddn.com
qiniu.bucket_sticker_name media
qiniu.bucket_sticker_domain http://pghnpyzos.bkt.clouddn.com
qiniu.bucket_moments_name media
qiniu.bucket_moments_domain http://pghnpyzos.bkt.clouddn.com
qiniu.bucket_portrait_name storage
qiniu.bucket_portrait_domain http://cdn2.wildfirechat.cn
qiniu.bucket_favorite_name storage
@@ -130,9 +154,12 @@ qiniu.bucket_favorite_domain http://cdn2.wildfirechat.cn
# 本地媒体服务器配置。
local.media.storage.root media
# 是否支持多端登陆
# 是否支持多端登陆,为true时支持任意平台任意多个客户端同时登录;为false时每个平台只支持一个端登录,但不同平台可以同时登录。
server.multi_endpoint false
# 多平台连接状态通知(仅当multi_endpoint为false时有效),true时移动端可以收到pc或web端登录的通知。
server.multi_platform_notification false
#*********************************************************************
# Push server configuration
#*********************************************************************
@@ -155,6 +182,8 @@ push.ios.server.address http://localhost:8085/ios/push
#mongodb.client_uri mongodb://host1:27017,host2:27017,host3:27017/wfchat?replicaSet=myReplicaSet
mongodb.client_uri mongodb://wfc:123456@localhost:27017/wfchat
mongodb.database wfchat
#仅在第一次启动时会设置消息数据的过期时间,如果之后再修改将不生效。
#如果需要修改过期时间,请修改t_messages_x和t_user_message_x的索引过期时间,修改方法请行百度
mongodb.data_expire_days 1096
#*********************************************************************
@@ -168,3 +197,6 @@ sensitive.filter.type 0
#*********************************************************************
##消息转发地址
#message.forward.url http://localhost:8087/message/forward
##设备信息转发地址
#things_message.forward.url http://localhost:8087/device/forward
@@ -0,0 +1,22 @@
DROP TABLE IF EXISTS `t_chatroom_blacklist`;
CREATE TABLE `t_chatroom_blacklist` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`_cid` varchar(64) NOT NULL,
`_uid` varchar(64) NOT NULL,
`_state` tinyint NOT NULL DEFAULT 0,
`_expired_time` bigint(20) NOT NULL,
`_dt` bigint(20) NOT NULL,
UNIQUE INDEX `cr_bl_uid_index` (`_cid`,_uid)
);
DROP TABLE IF EXISTS `t_chatroom_manager`;
CREATE TABLE `t_chatroom_manager` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`_cid` varchar(64) NOT NULL,
`_uid` varchar(64) NOT NULL,
`_state` tinyint NOT NULL DEFAULT 0,
`_dt` bigint(20) NOT NULL,
UNIQUE INDEX `cr_man_uid_index` (`_cid`,_uid)
);
+2
View File
@@ -0,0 +1,2 @@
alter table `t_user_messages` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages` ADD INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
+22
View File
@@ -0,0 +1,22 @@
DROP TABLE IF EXISTS `t_thing`;
DROP TABLE IF EXISTS `t_device`;
CREATE TABLE `t_device` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`_uid` varchar(64) NOT NULL,
`_token` varchar(64) DEFAULT '',
`_state` tinyint DEFAULT 0,
`_extra` TEXT DEFAULT NULL,
`_dt` bigint(20) NOT NULL,
UNIQUE INDEX `device_uid_index` (`_uid` ASC)
);
DROP TABLE IF EXISTS `t_user_device`;
CREATE TABLE `t_user_device` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`_uid` varchar(64) NOT NULL,
`_did` varchar(64) DEFAULT '',
INDEX `user_device_uid_index` (`_uid` ASC),
INDEX `user_device_did_index` (`_did` ASC)
);
+1
View File
@@ -0,0 +1 @@
alter table t_user_session add column `_user_type` tinyint DEFAULT 0;
+42
View File
@@ -0,0 +1,42 @@
DROP TABLE IF EXISTS `t_read_report`;
CREATE TABLE `t_read_report` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`_uid` varchar(64) NULL,
`_type` tinyint NULL,
`_line` int(11) NULL,
`_target` varchar(64) NULL,
`_dt` bigint(20) NOT NULL DEFAULT 0,
INDEX `read_report_index` (`_uid`, `_type`, `_line`, `_target`)
);
DROP TABLE IF EXISTS `t_user_read_report`;
CREATE TABLE `t_user_read_report` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`_rid` int(11) NOT NULL,
`_uid` varchar(64) NOT NULL,
`_seq` bigint(20) NOT NULL,
`_dt` DATETIME NOT NULL DEFAULT NOW(),
INDEX `user_read_report_index` (`_uid` DESC, `_seq` DESC),
UNIQUE INDEX `user_read_report_index2` (`_uid` DESC, `_rid` DESC)
);
DROP TABLE IF EXISTS `t_delivery_report`;
CREATE TABLE `t_delivery_report` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`_uid` varchar(64) NOT NULL,
`_dt` bigint(20) NOT NULL,
UNIQUE INDEX `delivery_index` (`_uid`)
);
DROP TABLE IF EXISTS `t_user_delivery_report`;
CREATE TABLE `t_user_delivery_report` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`_rid` varchar(64) NOT NULL,
`_uid` varchar(64) NOT NULL,
`_seq` bigint(20) NOT NULL,
`_dt` DATETIME NOT NULL DEFAULT NOW(),
INDEX `user_delivery_index` (`_uid` DESC, `_seq` DESC),
UNIQUE INDEX `user_delivery_index2` (`_uid` DESC, `_rid` DESC)
);
+1
View File
@@ -0,0 +1 @@
alter table t_group_member add column `_create_dt` bigint(20) DEFAULT 0;
@@ -0,0 +1,2 @@
alter table `t_group` add column `_history_message` tinyint NOT NULL DEFAULT 0;
alter table `t_group` add column `_max_member_count` int(11) NOT NULL DEFAULT 2000;
+2
View File
@@ -0,0 +1,2 @@
alter table `t_settings` change column `value` `_value` varchar(64) NOT NULL;
alter table `t_settings` change column `desc` `_desc` varchar(64) NOT NULL;
@@ -0,0 +1,30 @@
DROP TABLE IF EXISTS `t_chatroom_blacklist`;
CREATE TABLE `t_chatroom_blacklist` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`_cid` varchar(64) NOT NULL,
`_uid` varchar(64) NOT NULL,
`_state` tinyint NOT NULL DEFAULT 0,
`_expired_time` bigint(20) NOT NULL,
`_dt` bigint(20) NOT NULL,
UNIQUE INDEX `cr_bl_uid_index` (`_cid`,_uid)
)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
DROP TABLE IF EXISTS `t_chatroom_manager`;
CREATE TABLE `t_chatroom_manager` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`_cid` varchar(64) NOT NULL,
`_uid` varchar(64) NOT NULL,
`_state` tinyint NOT NULL DEFAULT 0,
`_dt` bigint(20) NOT NULL,
UNIQUE INDEX `cr_man_uid_index` (`_cid`,_uid)
)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
+260
View File
@@ -0,0 +1,260 @@
alter table `t_user_messages` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_0` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_1` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_2` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_3` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_4` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_5` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_6` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_7` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_8` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_9` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_10` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_11` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_12` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_13` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_14` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_15` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_16` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_17` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_18` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_19` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_20` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_21` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_22` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_23` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_24` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_25` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_26` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_27` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_28` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_29` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_30` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_31` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_32` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_33` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_34` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_35` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_36` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_37` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_38` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_39` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_40` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_41` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_42` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_43` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_44` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_45` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_46` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_47` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_48` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_49` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_50` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_51` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_52` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_53` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_54` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_55` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_56` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_57` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_58` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_59` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_60` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_61` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_62` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_63` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_64` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_65` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_66` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_67` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_68` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_69` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_70` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_71` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_72` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_73` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_74` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_75` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_76` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_77` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_78` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_79` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_80` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_81` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_82` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_83` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_84` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_85` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_86` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_87` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_88` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_89` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_90` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_91` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_92` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_93` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_94` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_95` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_96` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_97` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_98` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_99` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_100` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_101` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_102` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_103` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_104` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_105` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_106` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_107` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_108` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_109` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_110` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_111` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_112` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_113` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_114` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_115` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_116` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_117` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_118` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_119` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_120` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_121` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_122` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_123` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_124` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_125` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_126` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages_127` add column `_line` int(11) NOT NULL DEFAULT 0;
alter table `t_user_messages` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_0` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_1` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_2` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_3` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_4` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_5` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_6` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_7` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_8` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_9` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_10` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_11` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_12` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_13` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_14` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_15` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_16` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_17` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_18` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_19` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_20` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_21` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_22` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_23` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_24` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_25` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_26` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_27` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_28` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_29` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_30` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_31` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_32` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_33` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_34` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_35` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_36` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_37` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_38` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_39` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_40` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_41` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_42` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_43` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_44` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_45` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_46` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_47` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_48` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_49` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_50` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_51` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_52` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_53` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_54` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_55` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_56` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_57` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_58` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_59` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_60` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_61` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_62` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_63` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_64` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_65` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_66` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_67` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_68` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_69` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_70` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_71` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_72` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_73` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_74` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_75` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_76` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_77` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_78` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_79` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_80` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_81` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_82` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_83` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_84` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_85` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_86` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_87` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_88` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_89` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_90` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_91` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_92` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_93` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_94` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_95` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_96` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_97` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_98` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_99` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_100` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_101` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_102` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_103` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_104` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_105` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_106` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_107` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_108` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_109` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_110` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_111` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_112` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_113` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_114` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_115` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_116` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_117` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_118` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_119` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_120` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_121` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_122` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_123` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_124` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_125` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_126` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
alter table `t_user_messages_127` add INDEX `message_mid_line_uid_index` ( `_uid` DESC, `_line` DESC, `_mid` DESC );
+28
View File
@@ -0,0 +1,28 @@
DROP TABLE IF EXISTS `t_thing`;
DROP TABLE IF EXISTS `t_device`;
CREATE TABLE `t_device` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`_uid` varchar(64) NOT NULL,
`_token` varchar(64) DEFAULT '',
`_state` tinyint DEFAULT 0,
`_extra` TEXT DEFAULT NULL,
`_dt` bigint(20) NOT NULL,
UNIQUE INDEX `device_uid_index` (`_uid` ASC)
)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
DROP TABLE IF EXISTS `t_user_device`;
CREATE TABLE `t_user_device` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`_uid` varchar(64) NOT NULL,
`_did` varchar(64) DEFAULT '',
UNIQUE INDEX `user_device_uid_index` (`_uid` ASC, `_did` ASC),
INDEX `user_device_did_index` (`_did` ASC)
)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
+1
View File
@@ -0,0 +1 @@
alter table t_user_session add column `_user_type` tinyint DEFAULT 0 COMMENT "0, normal user; 1, robot; 2, device;";
+54
View File
@@ -0,0 +1,54 @@
DROP TABLE IF EXISTS `t_read_report`;
CREATE TABLE `t_read_report` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`_uid` varchar(64) NULL,
`_type` tinyint NULL,
`_line` int(11) NULL,
`_target` varchar(64) NULL,
`_dt` bigint(20) NOT NULL DEFAULT 0,
INDEX `read_report_index` (`_uid`, `_type`, `_line`, `_target`)
)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
DROP TABLE IF EXISTS `t_user_read_report`;
CREATE TABLE `t_user_read_report` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`_rid` int(11) NOT NULL,
`_uid` varchar(64) NOT NULL,
`_seq` bigint(20) NOT NULL,
`_dt` DATETIME NOT NULL DEFAULT NOW(),
INDEX `user_read_report_index` (`_uid` DESC, `_seq` DESC),
UNIQUE INDEX `user_read_report_index2` (`_uid` DESC, `_rid` DESC)
)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
DROP TABLE IF EXISTS `t_delivery_report`;
CREATE TABLE `t_delivery_report` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`_uid` varchar(64) NOT NULL,
`_dt` bigint(20) NOT NULL,
UNIQUE INDEX `delivery_index` (`_uid`)
)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
DROP TABLE IF EXISTS `t_user_delivery_report`;
CREATE TABLE `t_user_delivery_report` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`_rid` varchar(64) NOT NULL,
`_uid` varchar(64) NOT NULL,
`_seq` bigint(20) NOT NULL,
`_dt` DATETIME NOT NULL DEFAULT NOW(),
INDEX `user_delivery_index` (`_uid` DESC, `_seq` DESC),
UNIQUE INDEX `user_delivery_index2` (`_uid` DESC, `_rid` DESC)
)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
+1
View File
@@ -0,0 +1 @@
alter table t_group_member add column `_create_dt` bigint(20) DEFAULT 0, COMMENT "group member create time";
@@ -0,0 +1,2 @@
alter table `t_group` add column `_history_message` tinyint NOT NULL DEFAULT 0, COMMENT "new group member can load group history messages";
alter table `t_group` add column `_max_member_count` int(11) NOT NULL DEFAULT 2000, COMMENT "max group member count";
+2
View File
@@ -0,0 +1,2 @@
alter table `t_settings` change column `value` `_value` varchar(64) NOT NULL;
alter table `t_settings` change column `desc` `_desc` varchar(64) NOT NULL;
@@ -0,0 +1,6 @@
程序会自动创建数据库和执行migrate里的数据库,不需要手动创建库和执行sql语句。
数据库版本管理使用了flyway,flyway进行数据库升级时会校验数据库脚本的有效性,如果修改过这里的脚本,下次升级时就会失败。
强烈不建议修改数据库表结构,如果有内容(比如默认用户或者默认机器人的属性)需要修改,可以等数据库升级完成后,通过命令行或者数据库客户端进行修改。
由于服务具有缓存,一般修改过数据库内容后要重启后才能生效。
+2 -2
View File
@@ -5,7 +5,7 @@
<relativePath>../</relativePath>
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.39</version>
<version>0.43</version>
</parent>
<artifactId>moquette-broker</artifactId>
@@ -48,7 +48,7 @@
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
<version>8.0.19</version>
</dependency>
<dependency>
@@ -23,6 +23,7 @@ public class PushMessage {
//推送类型,android推送分为小米/华为/魅族等。ios分别为开发和发布。
public int pushType;
public String pushContent;
public String pushData;
public int unReceivedMsg;
public int mentionedType;
public String packageName;
@@ -109,7 +109,8 @@ public class FileAction extends Action {
}
// 路径安全检查
if (httpPath.contains("/.") || httpPath.contains("./") || httpPath.charAt(0) == '.' || httpPath.charAt(httpPath.length() - 1) == '.' || ReUtil.isMatch(INSECURE_URI, httpPath)) {
String path = httpPath.substring(0, httpPath.lastIndexOf("/"));
if (path.contains("/.") || path.contains("./") || path.charAt(0) == '.' || path.charAt(path.length() - 1) == '.' || ReUtil.isMatch(INSECURE_URI, path)) {
return null;
}
@@ -14,6 +14,7 @@ import cn.wildfirechat.pojos.InputGetGroup;
import cn.wildfirechat.pojos.OutputGroupMemberList;
import cn.wildfirechat.pojos.PojoGroupInfo;
import cn.wildfirechat.pojos.PojoGroupMember;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
@@ -56,6 +57,9 @@ public class GetGroupMembersAction extends AdminAction {
OutputGroupMemberList out = new OutputGroupMemberList();
out.setMembers(new ArrayList<>());
for (WFCMessage.GroupMember member : members) {
if (member.getType() == ProtoConstants.GroupMemberType.GroupMemberType_Removed) {
continue;
}
PojoGroupMember pm = new PojoGroupMember();
pm.setMember_id(member.getMemberId());
pm.setAlias(member.getAlias());
@@ -77,6 +77,10 @@ public final class BrokerConstants {
public static final String QINIU_BUCKET_VIDEO_DOMAIN = "qiniu.bucket_video_domain";
public static final String QINIU_BUCKET_FILE_NAME= "qiniu.bucket_file_name";
public static final String QINIU_BUCKET_FILE_DOMAIN = "qiniu.bucket_file_domain";
public static final String QINIU_BUCKET_STICKER_NAME= "qiniu.bucket_sticker_name";
public static final String QINIU_BUCKET_STICKER_DOMAIN = "qiniu.bucket_sticker_domain";
public static final String QINIU_BUCKET_MOMENTS_NAME= "qiniu.bucket_moments_name";
public static final String QINIU_BUCKET_MOMENTS_DOMAIN = "qiniu.bucket_moments_domain";
public static final String QINIU_BUCKET_PORTRAIT_NAME= "qiniu.bucket_portrait_name";
public static final String QINIU_BUCKET_PORTRAIT_DOMAIN = "qiniu.bucket_portrait_domain";
public static final String QINIU_BUCKET_FAVORITE_NAME= "qiniu.bucket_favorite_name";
@@ -110,6 +114,7 @@ public final class BrokerConstants {
public static final String MESSAGE_Forward_Url = "message.forward.url";
public static final String SERVER_MULTI_ENDPOINT = "server.multi_endpoint";
public static final String SERVER_MULTI_PLATFROM_NOTIFICATION = "server.multi_platform_notification";
public static final String MONGODB_Client_URI = "mongodb.client_uri";
public static final String MONGODB_Database = "mongodb.database";
@@ -123,13 +128,19 @@ public final class BrokerConstants {
public static final String MESSAGE_Disable_Stranger_Chat = "message.disable_stranger_chat";
public static final String MESSAGE_Blacklist_Strategy = "message.blacklist.strategy";
public static final String FRIEND_Disable_Search = "friend.disable_search";
public static final String FRIEND_Disable_NickName_Search = "friend.disable_nick_name_search";
public static final String FRIEND_Disable_Friend_Request = "friend.disable_friend_request";
public static final String FRIEND_Repeat_Request_Duration = "friend.repeat_request_duration";
public static final String FRIEND_Reject_Request_Duration = "friend.reject_request_duration";
public static final String FRIEND_Request_Expiration_Duration = "friend.request_expiration_duration";
public static final String FRIEND_New_Welcome_Message = "friend.new_welcome_message";
public static final String CHATROOM_Participant_Idle_Time = "chatroom.participant_idle_time";
public static final String CHATROOM_Rejoin_When_Active = "chatroom.rejoin_when_active";
public static final String MESSAGES_DISABLE_REMOTE_SEARCH = "message.disable_remote_search";
private BrokerConstants() {
}
@@ -60,6 +60,14 @@ public class GetMediaUploadTokenHandler extends IMHandler<WFCMessage.GetUploadTo
bucketName = MediaServerConfig.QINIU_BUCKET_FAVORITE_NAME;
bucketDomain = MediaServerConfig.QINIU_BUCKET_FAVORITE_DOMAIN;
break;
case 7:
bucketName = MediaServerConfig.QINIU_BUCKET_STICKER_NAME;
bucketDomain = MediaServerConfig.QINIU_BUCKET_STICKER_DOMAIN;
break;
case 8:
bucketName = MediaServerConfig.QINIU_BUCKET_MOMENTS_NAME;
bucketDomain = MediaServerConfig.QINIU_BUCKET_MOMENTS_DOMAIN;
break;
default:
bucketName = MediaServerConfig.QINIU_BUCKET_GENERAL_NAME;
bucketDomain = MediaServerConfig.QINIU_BUCKET_GENERAL_DOMAIN;
@@ -67,6 +67,14 @@ public class GetQiniuUploadTokenHandler extends IMHandler<Byte> {
bucketName = MediaServerConfig.QINIU_BUCKET_FAVORITE_NAME;
bucketDomain = MediaServerConfig.QINIU_BUCKET_FAVORITE_DOMAIN;
break;
case 7:
bucketName = MediaServerConfig.QINIU_BUCKET_STICKER_NAME;
bucketDomain = MediaServerConfig.QINIU_BUCKET_STICKER_DOMAIN;
break;
case 8:
bucketName = MediaServerConfig.QINIU_BUCKET_MOMENTS_NAME;
bucketDomain = MediaServerConfig.QINIU_BUCKET_MOMENTS_DOMAIN;
break;
default:
bucketName = MediaServerConfig.QINIU_BUCKET_GENERAL_NAME;
bucketDomain = MediaServerConfig.QINIU_BUCKET_GENERAL_DOMAIN;
@@ -17,8 +17,10 @@ import java.util.List;
abstract public class GroupHandler<T> extends IMHandler<T> {
protected void sendGroupNotification(String fromUser, String targetId, List<Integer> lines, WFCMessage.MessageContent content) {
if (lines != null) {
if (lines == null) {
lines = new ArrayList<>();
} else {
lines = new ArrayList<>(lines);
}
if (lines.isEmpty()) {
@@ -31,7 +31,7 @@ public class HandleFriendRequestHandler extends IMHandler<WFCMessage.HandleFrien
ErrorCode errorCode = m_messagesStore.handleFriendRequest(fromUser, request, builder, heads, isAdmin);
if (errorCode == ERROR_CODE_SUCCESS) {
if (!isAdmin && builder.getConversation() != null) {
if (!isAdmin && builder.getConversation() != null && request.getStatus() == ProtoConstants.FriendRequestStatus.RequestStatus_Accepted) {
long messageId = MessageShardingUtil.generateId();
long timestamp = System.currentTimeMillis();
builder.setMessageId(messageId);
@@ -43,7 +43,12 @@ public class HandleFriendRequestHandler extends IMHandler<WFCMessage.HandleFrien
if (session != null && !StringUtil.isNullOrEmpty(session.getLanguage())) {
language = session.getLanguage();
}
WFCMessage.MessageContent.Builder contentBuilder = WFCMessage.MessageContent.newBuilder().setType(90).setContent(I18n.getString(language, "Above_Greeting_Message"));
WFCMessage.MessageContent.Builder contentBuilder = WFCMessage.MessageContent.newBuilder();
if (m_messagesStore.isNewFriendWelcomeMessage()) {
contentBuilder.setType(92);
} else {
contentBuilder.setType(90).setContent(I18n.getString(language, "Above_Greeting_Message"));
}
builder = WFCMessage.Message.newBuilder();
builder.setFromUser(request.getTargetUid());
@@ -56,7 +61,12 @@ public class HandleFriendRequestHandler extends IMHandler<WFCMessage.HandleFrien
builder.setMessageId(messageId);
saveAndPublish(request.getTargetUid(), null, builder.build(), false);
contentBuilder.setContent(I18n.getString(language, "Friend_Can_Start_Chat"));
if (m_messagesStore.isNewFriendWelcomeMessage()) {
contentBuilder.setType(93);
} else {
contentBuilder.setContent(I18n.getString(language, "Friend_Can_Start_Chat"));
}
builder.setContent(contentBuilder);
messageId = MessageShardingUtil.generateId();
builder.setMessageId(messageId);
@@ -64,9 +74,9 @@ public class HandleFriendRequestHandler extends IMHandler<WFCMessage.HandleFrien
builder.setServerTimestamp(timestamp);
saveAndPublish(request.getTargetUid(), null, builder.build(), false);
publisher.publishNotification(IMTopic.NotifyFriendTopic, request.getTargetUid(), heads[0]);
publisher.publishNotification(IMTopic.NotifyFriendTopic, fromUser, heads[1]);
}
publisher.publishNotification(IMTopic.NotifyFriendTopic, request.getTargetUid(), heads[0]);
publisher.publishNotification(IMTopic.NotifyFriendTopic, fromUser, heads[1]);
}
return errorCode;
}
@@ -65,6 +65,9 @@ abstract public class IMHandler<T> {
protected static String actionName;
public static MessagesPublisher getPublisher() {
return publisher;
}
public IMHandler() {
try {
@@ -0,0 +1,33 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package io.moquette.imhandler;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.GroupNotificationBinaryContent;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
import com.hazelcast.util.StringUtil;
import io.moquette.spi.impl.Qos1PublishHandler;
import io.netty.buffer.ByteBuf;
import static win.liyufan.im.IMTopic.KickoffGroupMemberTopic;
import static win.liyufan.im.IMTopic.KickoffPCClientTopic;
@Handler(value = KickoffPCClientTopic)
public class KickoffPCClientHandler extends GroupHandler<WFCMessage.IDBuf> {
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.IDBuf request, Qos1PublishHandler.IMCallback callback) {
String pcClientId = request.getId();
if (StringUtil.isNullOrEmpty(pcClientId)) {
return ErrorCode.INVALID_PARAMETER;
}
return m_sessionsStore.kickoffPCClient(fromUser, pcClientId);
}
}
@@ -18,8 +18,7 @@ import win.liyufan.im.IMTopic;
public class PutUserSettingHandler extends IMHandler<WFCMessage.ModifyUserSettingReq> {
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.ModifyUserSettingReq request, Qos1PublishHandler.IMCallback callback) {
long timestamp = m_messagesStore.updateUserSettings(fromUser, request);
publisher.publishNotification(IMTopic.NotifyUserSettingTopic, fromUser, timestamp);
m_messagesStore.updateUserSettings(fromUser, request);
return ErrorCode.ERROR_CODE_SUCCESS;
}
}
@@ -21,13 +21,12 @@ import java.util.Set;
public class RecallMessageHandler extends IMHandler<WFCMessage.INT64Buf> {
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, boolean isAdmin, WFCMessage.INT64Buf int64Buf, Qos1PublishHandler.IMCallback callback) {
ErrorCode errorCode = m_messagesStore.recallMessage(int64Buf.getId(), fromUser, isAdmin);
ErrorCode errorCode = m_messagesStore.recallMessage(int64Buf.getId(), fromUser, clientID, isAdmin);
if(errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
return errorCode;
}
Set<String> notifyReceivers = new LinkedHashSet<>();
WFCMessage.Message message = m_messagesStore.getMessage(int64Buf.getId());
if (message == null) {
return ErrorCode.ERROR_CODE_NOT_EXIST;
@@ -35,11 +34,6 @@ public class RecallMessageHandler extends IMHandler<WFCMessage.INT64Buf> {
publish(fromUser, clientID, message);
//等待客户端实现根据撤回消息更新内容,之后可以删掉这段代码
m_messagesStore.getNotifyReceivers(fromUser, message.toBuilder(), notifyReceivers, false);
this.publisher.publishRecall2Receivers(int64Buf.getId(), fromUser, notifyReceivers, clientID);
return errorCode;
}
@@ -33,13 +33,16 @@ import java.util.function.Function;
import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent;
import static io.moquette.persistence.MemoryMessagesStore.USER_STATUS;
import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE;
import static cn.wildfirechat.proto.ProtoConstants.SearchUserType.*;
public class DatabaseStore {
private static final Logger LOG = LoggerFactory.getLogger(DatabaseStore.class);
private final ThreadPoolExecutorWrapper mScheduler;
private boolean disableRemoteMessageSearch = false;
public void setDisableRemoteMessageSearch(boolean disableRemoteMessageSearch) {
this.disableRemoteMessageSearch = disableRemoteMessageSearch;
}
public DatabaseStore(ThreadPoolExecutorWrapper scheduler) {
this.mScheduler = scheduler;
@@ -83,10 +86,10 @@ public class DatabaseStore {
try {
connection = DBUtil.getConnection();
String sql = "insert into t_settings " +
" (`id`, `value`, `desc`) values(?, ?, ?)" +
" (`id`, `_value`, `_desc`) values(?, ?, ?)" +
" ON DUPLICATE KEY UPDATE " +
"`value` = ?," +
"`desc` = ?";
"`_value` = ?," +
"`_desc` = ?";
statement = connection.prepareStatement(sql);
@@ -117,7 +120,7 @@ public class DatabaseStore {
try {
connection = DBUtil.getConnection();
String sql = "select `value`, `desc` from t_settings where `id` = ?";
String sql = "select `_value`, `_desc` from t_settings where `id` = ?";
statement = connection.prepareStatement(sql);
int index = 1;
@@ -328,7 +331,7 @@ public class DatabaseStore {
String sql = "select `_mid`" +
", `_alias`" +
", `_type`" +
", `_dt` from t_group_member where _gid = ?";
", `_dt`, `_create_dt` from t_group_member where _gid = ?";
statement = connection.prepareStatement(sql);
statement.setString(1, groupId);
@@ -355,6 +358,9 @@ public class DatabaseStore {
long longValue = rs.getLong(index++);
builder.setUpdateDt(longValue);
longValue = rs.getLong(index++);
builder.setCreateDt(longValue);
WFCMessage.GroupMember member = builder.build();
groupMembers.put(groupId, member);
}
@@ -494,13 +500,24 @@ public class DatabaseStore {
PreparedStatement statement = null;
try {
connection = DBUtil.getConnection();
String sql = "insert into " + MessageShardingUtil.getMessageTable(message.getMessageId()) +
" (`_mid`, `_from`, `_type`, `_target`, `_line`, `_data`, `_searchable_key`, `_dt`, `_content_type`, `_to`) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" +
" ON DUPLICATE KEY UPDATE " +
"`_data` = ?," +
"`_searchable_key` = ?," +
"`_dt` = ?," +
"`_content_type` = ?";
String table = MessageShardingUtil.getMessageTable(message.getMessageId());
String sql;
if (disableRemoteMessageSearch) {
sql = "insert into " + table +
" (`_mid`, `_from`, `_type`, `_target`, `_line`, `_data`, `_dt`, `_content_type`, `_to`) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" +
" ON DUPLICATE KEY UPDATE " +
"`_data` = ?," +
"`_dt` = ?," +
"`_content_type` = ?";
} else {
sql = "insert into " + table +
" (`_mid`, `_from`, `_type`, `_target`, `_line`, `_data`, `_searchable_key`, `_dt`, `_content_type`, `_to`) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" +
" ON DUPLICATE KEY UPDATE " +
"`_data` = ?," +
"`_searchable_key` = ?," +
"`_dt` = ?," +
"`_content_type` = ?";
}
String searchableContent = message.getContent().getSearchableContent() == null ? "" : message.getContent().getSearchableContent();
@@ -514,7 +531,9 @@ public class DatabaseStore {
Blob blob = connection.createBlob();
blob.setBytes(1, message.getContent().toByteArray());
statement.setBlob(index++, blob);
statement.setString(index++, searchableContent);
if (!disableRemoteMessageSearch) {
statement.setString(index++, searchableContent);
}
statement.setTimestamp(index++, new Timestamp(message.getServerTimestamp()));
statement.setInt(index++, message.getContent().getType());
String to = message.getToUser();
@@ -526,7 +545,9 @@ public class DatabaseStore {
statement.setString(index++, to);
statement.setBlob(index++, blob);
statement.setString(index++, searchableContent);
if (!disableRemoteMessageSearch) {
statement.setString(index++, searchableContent);
}
statement.setTimestamp(index++, new Timestamp(message.getServerTimestamp()));
statement.setInt(index++, message.getContent().getType());
@@ -805,7 +826,16 @@ public class DatabaseStore {
}
}
WFCMessage.Message message = builder.build();
messages.add(message);
boolean expired = false;
if (message.getContent().getExpireDuration() > 0) {
if (System.currentTimeMillis() > message.getServerTimestamp() + message.getContent().getExpireDuration()*1000) {
expired = true;
}
}
if (!expired) {
messages.add(message);
}
}
if (count == 0) {
@@ -1320,7 +1350,6 @@ public class DatabaseStore {
}
void updateSessionDeleted(String uid, String cid, int deleted) {
mScheduler.execute(()->{
Connection connection = null;
PreparedStatement statement = null;
@@ -1345,11 +1374,9 @@ public class DatabaseStore {
} finally {
DBUtil.closeDB(connection, statement);
}
});
}
void updateSessionPlatform(String uid, String cid, int platform) {
mScheduler.execute(()->{
Connection connection = null;
PreparedStatement statement = null;
@@ -1374,7 +1401,6 @@ public class DatabaseStore {
} finally {
DBUtil.closeDB(connection, statement);
}
});
}
private boolean strEqual(String left, String right) {
@@ -1476,7 +1502,7 @@ public class DatabaseStore {
try {
connection = DBUtil.getConnection();
String sql;
if (platform == ProtoConstants.Platform.Platform_Windows || platform == ProtoConstants.Platform.Platform_OSX || platform == ProtoConstants.Platform.Platform_Linux) {
if (platform == ProtoConstants.Platform.Platform_Windows || platform == ProtoConstants.Platform.Platform_OSX || platform == ProtoConstants.Platform.Platform_LINUX) {
sql = "update t_user_session set `_deleted` = ?, `_token` = ?, `_voip_token` = ?, `_dt` = ? where `_uid`=? and (`_platform` = ? or `_platform` = ? or `_platform` = ?) and `_cid` <> ? and `_deleted` = 0";
} else if(platform == ProtoConstants.Platform.Platform_iOS || platform == ProtoConstants.Platform.Platform_Android) {
sql = "update t_user_session set `_deleted` = ?, `_token` = ?, `_voip_token` = ?, `_dt` = ? where `_uid`=? and (`_platform` = ? or `_platform` = ?) and `_cid` <> ? and `_deleted` = 0";
@@ -1494,10 +1520,10 @@ public class DatabaseStore {
statement.setString(index++, uid);
if (platform == ProtoConstants.Platform.Platform_Windows || platform == ProtoConstants.Platform.Platform_OSX || platform == ProtoConstants.Platform.Platform_Linux) {
if (platform == ProtoConstants.Platform.Platform_Windows || platform == ProtoConstants.Platform.Platform_OSX || platform == ProtoConstants.Platform.Platform_LINUX) {
statement.setInt(index++, ProtoConstants.Platform.Platform_Windows);
statement.setInt(index++, ProtoConstants.Platform.Platform_OSX);
statement.setInt(index++, ProtoConstants.Platform.Platform_Linux);
statement.setInt(index++, ProtoConstants.Platform.Platform_LINUX);
} else if(platform == ProtoConstants.Platform.Platform_iOS || platform == ProtoConstants.Platform.Platform_Android) {
statement.setInt(index++, ProtoConstants.Platform.Platform_iOS);
statement.setInt(index++, ProtoConstants.Platform.Platform_Android);
@@ -1634,7 +1660,7 @@ public class DatabaseStore {
", `_mid`" +
", `_alias`" +
", `_type`" +
", `_dt`) values(?, ?, ?, ?, ?)" +
", `_dt`, `_create_dt`) values(?, ?, ?, ?, ?, ?)" +
" ON DUPLICATE KEY UPDATE " +
"`_alias` = ?," +
"`_type` = ?," +
@@ -1655,6 +1681,7 @@ public class DatabaseStore {
statement.setString(index++, member.getAlias());
statement.setInt(index++, member.getType());
statement.setLong(index++, dt);
statement.setLong(index++, member.getCreateDt());
statement.setString(index++, member.getAlias());
statement.setInt(index++, member.getType());
statement.setLong(index++, dt);
@@ -26,6 +26,7 @@ import com.xiaoleilu.loServer.model.FriendData;
import cn.wildfirechat.pojos.InputOutputUserBlockStatus;
import cn.wildfirechat.common.ErrorCode;
import io.moquette.BrokerConstants;
import io.moquette.imhandler.IMHandler;
import io.moquette.server.Constants;
import io.moquette.server.Server;
import io.moquette.spi.IMatchingCondition;
@@ -33,6 +34,7 @@ import io.moquette.spi.IMessagesStore;
import io.moquette.spi.security.Tokenor;
import io.moquette.spi.impl.subscriptions.Topic;
import io.netty.handler.codec.mqtt.MqttVersion;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import win.liyufan.im.*;
@@ -55,10 +57,12 @@ import static cn.wildfirechat.proto.ProtoConstants.GroupMemberType.*;
import static cn.wildfirechat.proto.ProtoConstants.ModifyChannelInfoType.*;
import static cn.wildfirechat.proto.ProtoConstants.ModifyGroupInfoType.*;
import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent;
import static cn.wildfirechat.proto.ProtoConstants.Platform.*;
import static io.moquette.BrokerConstants.*;
import static io.moquette.server.Constants.MAX_CHATROOM_MESSAGE_QUEUE;
import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE;
import static win.liyufan.im.MyInfoType.*;
import static win.liyufan.im.UserSettingScope.kUserSettingPCOnline;
public class MemoryMessagesStore implements IMessagesStore {
private static final String MESSAGES_MAP = "messages_map";
@@ -118,10 +122,15 @@ public class MemoryMessagesStore implements IMessagesStore {
private ConcurrentHashMap<String, Boolean> userPushHiddenDetail = new ConcurrentHashMap<>();
private ConcurrentHashMap<String, Boolean> userConvSlientMap = new ConcurrentHashMap<>();
private boolean mDisableSearch = false;
private boolean mDisableNicknameSearch = false;
private boolean mDisableFriendRequest = false;
private long mFriendRequestDuration = 7 * 24 * 60 * 60 * 1000;
private long mFriendRejectDuration = 30 * 24 * 60 * 60 * 1000;
private long mFriendRequestExpiration = 7 * 24 * 60 * 60 * 1000;
private boolean mFriendNewWelcomeMessage = false;
private boolean mMultiPlatformNotification = false;
private boolean mDisableStrangerChat = false;
private long mChatroomParticipantIdleTime = 900000;
@@ -130,6 +139,7 @@ public class MemoryMessagesStore implements IMessagesStore {
MemoryMessagesStore(Server server, DatabaseStore databaseStore) {
m_Server = server;
this.databaseStore = databaseStore;
IS_MESSAGE_ROAMING = "1".equals(m_Server.getConfig().getProperty(MESSAGE_ROAMING));
IS_MESSAGE_REMOTE_HISTORY_MESSAGE = "1".equals(m_Server.getConfig().getProperty(MESSAGE_Remote_History_Message));
Constants.MAX_MESSAGE_QUEUE = Integer.parseInt(m_Server.getConfig().getProperty(MESSAGE_Max_Queue));
@@ -139,6 +149,37 @@ public class MemoryMessagesStore implements IMessagesStore {
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
printMissConfigLog(MESSAGE_Disable_Stranger_Chat, mDisableStrangerChat + "");
}
try {
mMultiPlatformNotification = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.SERVER_MULTI_PLATFROM_NOTIFICATION, "false"));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
printMissConfigLog(SERVER_MULTI_PLATFROM_NOTIFICATION, mDisableStrangerChat + "");
}
try {
mDisableSearch = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.FRIEND_Disable_Search));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
printMissConfigLog(FRIEND_Disable_Search, mDisableSearch + "");
}
try {
mDisableNicknameSearch = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.FRIEND_Disable_NickName_Search));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
printMissConfigLog(FRIEND_Disable_NickName_Search, mDisableNicknameSearch + "");
}
try {
mDisableFriendRequest = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.FRIEND_Disable_Friend_Request));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
printMissConfigLog(FRIEND_Disable_Friend_Request, mDisableFriendRequest + "");
}
try {
@@ -146,6 +187,7 @@ public class MemoryMessagesStore implements IMessagesStore {
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
printMissConfigLog(FRIEND_Repeat_Request_Duration, mFriendRequestDuration + "");
}
try {
@@ -153,6 +195,7 @@ public class MemoryMessagesStore implements IMessagesStore {
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
printMissConfigLog(FRIEND_Reject_Request_Duration, mFriendRejectDuration + "");
}
try {
@@ -160,13 +203,24 @@ public class MemoryMessagesStore implements IMessagesStore {
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
printMissConfigLog(FRIEND_Request_Expiration_Duration, mFriendRequestExpiration + "");
}
try {
mFriendNewWelcomeMessage = Boolean.parseBoolean(m_Server.getConfig().getProperty(FRIEND_New_Welcome_Message));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
printMissConfigLog(FRIEND_New_Welcome_Message, mFriendNewWelcomeMessage + "");
}
try {
mChatroomRejoinWhenActive = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.CHATROOM_Rejoin_When_Active));
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
printMissConfigLog(CHATROOM_Rejoin_When_Active, mChatroomRejoinWhenActive + "");
}
try {
@@ -174,7 +228,18 @@ public class MemoryMessagesStore implements IMessagesStore {
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
printMissConfigLog(CHATROOM_Participant_Idle_Time, mChatroomParticipantIdleTime + "");
}
try {
boolean disableRemoteMessageSearch = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.MESSAGES_DISABLE_REMOTE_SEARCH, "false"));
databaseStore.setDisableRemoteMessageSearch(disableRemoteMessageSearch);
} catch (Exception e) {
}
}
private void printMissConfigLog(String config, String defaultValue) {
LOG.info("配置文件中缺少配置项目 {}, 缺省值为 {},可以忽略本提醒,或者更新配置项", config, defaultValue);
}
@Override
@@ -428,7 +493,7 @@ public class MemoryMessagesStore implements IMessagesStore {
}
if (bundle.getMessage().getContent().getExpireDuration() > 0) {
if (System.currentTimeMillis() < bundle.getMessage().getServerTimestamp() + bundle.getMessage().getContent().getExpireDuration()) {
if (System.currentTimeMillis() > bundle.getMessage().getServerTimestamp() + bundle.getMessage().getContent().getExpireDuration()*1000) {
continue;
}
}
@@ -522,6 +587,12 @@ public class MemoryMessagesStore implements IMessagesStore {
MessageBundle bundle = mIMap.get(targetMessageId);
if (bundle != null) {
if (exceptClientId == null || !exceptClientId.equals(bundle.getFromClientId()) || !fromUser.equals(bundle.getFromUser())) {
if (bundle.getMessage().getContent().getExpireDuration() > 0) {
if (System.currentTimeMillis() > bundle.getMessage().getServerTimestamp() + bundle.getMessage().getContent().getExpireDuration() * 1000) {
continue;
}
}
size += bundle.getMessage().getSerializedSize();
if (size >= 3 * 1024 * 1024) { //3M
break;
@@ -727,9 +798,9 @@ public class MemoryMessagesStore implements IMessagesStore {
List<WFCMessage.GroupMember> updatedMemberList = new ArrayList<>();
for (WFCMessage.GroupMember member : memberList) {
if (member.getMemberId().equals(groupInfo.getOwner())) {
member = member.toBuilder().setUpdateDt(dt).setType(ProtoConstants.GroupMemberType.GroupMemberType_Owner).build();
member = member.toBuilder().setUpdateDt(dt).setCreateDt(dt).setType(ProtoConstants.GroupMemberType.GroupMemberType_Owner).build();
} else {
member = member.toBuilder().setUpdateDt(dt).build();
member = member.toBuilder().setUpdateDt(dt).setCreateDt(dt).build();
}
groupMembers.put(groupId, member);
updatedMemberList.add(member);
@@ -752,6 +823,8 @@ public class MemoryMessagesStore implements IMessagesStore {
}
int maxCount = Integer.MAX_VALUE;
if (!isAdmin) {
boolean isMember = false;
boolean isManager = false;
@@ -781,6 +854,15 @@ public class MemoryMessagesStore implements IMessagesStore {
if (!isMember && !(memberList.size() == 1 && operator.equals(memberList.get(0).getMemberId()))) {
return ErrorCode.ERROR_CODE_NOT_IN_GROUP;
}
SystemSettingPojo maxMemberSetting = databaseStore.getSystemSetting(ProtoConstants.SystemSettingType.Group_Max_Member_Count);
if (maxMemberSetting != null) {
try {
maxCount = Integer.parseInt(maxMemberSetting.value);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
long updateDt = System.currentTimeMillis();
@@ -789,9 +871,9 @@ public class MemoryMessagesStore implements IMessagesStore {
ArrayList<String> newInviteUsers = new ArrayList<>();
for (WFCMessage.GroupMember member : memberList) {
if (member.getMemberId().equals(groupInfo.getOwner())) {
member = member.toBuilder().setType(GroupMemberType_Owner).setUpdateDt(updateDt).setAlias("").build();
member = member.toBuilder().setType(GroupMemberType_Owner).setUpdateDt(updateDt).setCreateDt(updateDt).setAlias("").build();
} else {
member = member.toBuilder().setType(GroupMemberType_Normal).setUpdateDt(updateDt).setAlias("").build();
member = member.toBuilder().setType(GroupMemberType_Normal).setUpdateDt(updateDt).setCreateDt(updateDt).setAlias("").build();
}
tmp.add(member);
newInviteUsers.add(member.getMemberId());
@@ -804,6 +886,18 @@ public class MemoryMessagesStore implements IMessagesStore {
members = loadGroupMemberFromDB(hzInstance, groupId);
}
if (maxCount != Integer.MAX_VALUE) {
int existCount = 0;
for (WFCMessage.GroupMember member : members) {
if (member.getType() != GroupMemberType_Removed) {
existCount++;
}
}
if (existCount + newInviteUsers.size() > maxCount) {
return ErrorCode.ERROR_CODE_GROUP_EXCEED_MAX_MEMBER_COUNT;
}
}
for (WFCMessage.GroupMember member : members) {
if (newInviteUsers.contains(member.getMemberId())) {
groupMembers.remove(groupId, member);
@@ -1009,15 +1103,23 @@ public class MemoryMessagesStore implements IMessagesStore {
}
if (oldInfo.getType() == ProtoConstants.GroupType.GroupType_Normal) {
if (oldInfo.getOwner() == null) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
if (!oldInfo.getOwner().equals(operator)) {
if (modifyType == Modify_Group_Extra) {
if (!operator.equals(oldInfo.getOwner())) {
WFCMessage.GroupMember gm = getGroupMember(groupId, operator);
boolean isManager = false;
if (gm != null && gm.getType() == GroupMemberType_Manager) {
isManager = true;
}
if (!isManager && modifyType != Modify_Group_Name && modifyType != Modify_Group_Portrait && modifyType != Modify_Group_Extra) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
}
}
if (oldInfo.getType() == ProtoConstants.GroupType.GroupType_Free) {
if (modifyType != Modify_Group_Name && modifyType != Modify_Group_Portrait && modifyType != Modify_Group_Extra) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
}
}
@@ -1322,7 +1424,7 @@ public class MemoryMessagesStore implements IMessagesStore {
}
@Override
public ErrorCode recallMessage(long messageUid, String operatorId, boolean isAdmin) {
public ErrorCode recallMessage(long messageUid, String operatorId, String clientId, boolean isAdmin) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
IMap<Long, MessageBundle> mIMap = hzInstance.getMap(MESSAGES_MAP);
@@ -1373,8 +1475,21 @@ public class MemoryMessagesStore implements IMessagesStore {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
message = message.toBuilder().setContent(message.getContent().toBuilder().setContent(operatorId).setType(80).clearSearchableContent().setData(ByteString.copyFrom(new StringBuffer().append(messageUid).toString().getBytes())).build()).build();
String searchContent = message.getContent().getSearchableContent() == null ? "" : message.getContent().getSearchableContent();
String cont = message.getContent().getContent() == null ? "" : message.getContent().getContent().replace("\"", "\\\"");
String extra = message.getContent().getExtra() == null ? "" : message.getContent().getExtra().replace("\"", "\\\"");
JSONObject json = new JSONObject();
json.put("s", message.getFromUser());
json.put("ts", message.getServerTimestamp());
json.put("t", message.getContent().getType());
json.put("sc", message.getContent().getSearchableContent());
json.put("c", message.getContent().getContent());
json.put("e", message.getContent().getExtra());
String recalledContent = json.toJSONString();
message = message.toBuilder().setContent(message.getContent().toBuilder().setContent(operatorId).setType(80).clearSearchableContent().setData(ByteString.copyFrom(String.valueOf(messageUid).getBytes())).setExtra(recalledContent).build()).build();
messageBundle.setMessage(message);
messageBundle.setFromClientId(clientId);
databaseStore.deleteMessage(messageUid);
@@ -1524,6 +1639,56 @@ public class MemoryMessagesStore implements IMessagesStore {
}
@Override
public void updateUserOnlineSetting(MemorySessionStore.Session session, boolean online) {
if(!mMultiPlatformNotification) {
return;
}
if (m_Server.getStore().sessionsStore().isMultiEndpointSupported()) {
return;
}
if (m_Server.isShutdowning()) {
return;
}
if (session.getPlatform() == Platform_LINUX || session.getPlatform() == Platform_Windows || session.getPlatform() == Platform_OSX) {
updateUserSettings(session.username, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("PC").setValue(online ? (System.currentTimeMillis() + "|" + session.getPlatform() + "|" + session.getClientID() + "|" + session.getPhoneName()) : "").build());
} else {
String value = null;
for (MemorySessionStore.Session s : m_Server.getStore().sessionsStore().sessionForUser(session.username)) {
if (s.getDeleted() != 0 || !m_Server.getConnectionsManager().isConnected(s.getClientID())) {
continue;
}
switch (s.getPlatform()) {
case Platform_LINUX:
case Platform_Windows:
case Platform_OSX:
value = System.currentTimeMillis() + "|" + s.getPlatform() + "|" + s.getClientID() + "|" + s.getPhoneName();
break;
default:
break;
}
if (value != null) {
break;
}
}
WFCMessage.UserSettingEntry pcentry = getUserSetting(session.getUsername(), kUserSettingPCOnline, "PC");
if (value != null) {
if (pcentry == null || StringUtil.isNullOrEmpty(pcentry.getValue())) {
updateUserSettings(session.username, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("PC").setValue(value).build());
}
} else {
if (pcentry != null && !StringUtil.isNullOrEmpty(pcentry.getValue())) {
updateUserSettings(session.username, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("PC").setValue("").build());
}
}
}
}
@Override
public ErrorCode modifyUserStatus(String userId, int status) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
@@ -1612,6 +1777,14 @@ public class MemoryMessagesStore implements IMessagesStore {
}
@Override
public List<WFCMessage.User> searchUser(String keyword, int searchType, int page) {
if (mDisableSearch) {
return new ArrayList<>();
}
if (mDisableNicknameSearch && searchType == ProtoConstants.SearchUserType.SearchUserType_General) {
searchType = ProtoConstants.SearchUserType.SearchUserType_Name_Mobile;
}
return databaseStore.searchUserFromDB(keyword, searchType, page);
}
@@ -1782,60 +1955,6 @@ public class MemoryMessagesStore implements IMessagesStore {
return ErrorCode.ERROR_CODE_SUCCESS;
}
@Override
public ErrorCode login(String name, String password, List<String> userIdRet) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet rs = null;
try {
connection = DBUtil.getConnection();
String sql = "select `_uid`, `_passwd_md5` from t_user where `_name` = ?";
statement = connection.prepareStatement(sql);
int index = 1;
statement.setString(index++, name);
rs = statement.executeQuery();
if (rs.next()) {
String uid = rs.getString(1);
int status = getUserStatus(uid);
if (status == 1) {
return ErrorCode.ERROR_CODE_USER_FORBIDDEN;
}
String pwd_md5 = rs.getString(2);
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
String passwdMd5 = Base64.getEncoder().encodeToString(md5.digest(password.getBytes("utf-8")));
if (passwdMd5.equals(pwd_md5)) {
LOG.info("login success userName={}, userId={}", name, uid);
userIdRet.add(uid);
return ErrorCode.ERROR_CODE_SUCCESS;
} else {
LOG.info("login failure incorrect password, userName={}, userId={}", name, uid);
return ErrorCode.ERROR_CODE_PASSWORD_INCORRECT;
}
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
LOG.info("login failure execption password, userName={}", name);
return ErrorCode.ERROR_CODE_PASSWORD_INCORRECT;
}
} else {
LOG.info("login failure user not exist, userName={}", name);
return ErrorCode.ERROR_CODE_NOT_EXIST;
}
} catch (SQLException e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
LOG.info("login failure db execption, userName={}", name);
return ErrorCode.ERROR_CODE_SERVER_ERROR;
} finally {
DBUtil.closeDB(connection, statement, rs);
}
}
synchronized Collection<FriendData> loadFriend(MultiMap<String, FriendData> friendsMap, String userId) {
Collection<FriendData> friends = databaseStore.getPersistFriends(userId);
if (friends != null) {
@@ -1945,6 +2064,10 @@ public class MemoryMessagesStore implements IMessagesStore {
@Override
public ErrorCode saveAddFriendRequest(String userId, WFCMessage.AddFriendRequest request, long[] head) {
if (mDisableFriendRequest) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
MultiMap<String, WFCMessage.FriendRequest> requestMap = hzInstance.getMultiMap(USER_FRIENDS_REQUEST);
Collection<WFCMessage.FriendRequest> requests = requestMap.get(userId);
@@ -2025,6 +2148,25 @@ public class MemoryMessagesStore implements IMessagesStore {
public ErrorCode handleFriendRequest(String userId, WFCMessage.HandleFriendRequest request, WFCMessage.Message.Builder msgBuilder, long[] heads, boolean isAdmin) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
if(request.getStatus() == ProtoConstants.FriendRequestStatus.RequestStatus_Accepted) {
MultiMap<String, FriendData> friendsMap = hzInstance.getMultiMap(USER_FRIENDS);
Collection<FriendData> friends = friendsMap.get(userId);
if (friends == null || friends.size() == 0) {
friends = loadFriend(friendsMap, userId);
}
for (FriendData fd : friends) {
if (fd.getFriendUid().equals(request.getTargetUid())) {
if (fd.getState() == 0) {
return ErrorCode.ERROR_CODE_ALREADY_FRIENDS;
} else {
break;
}
}
}
}
if (isAdmin) {
MultiMap<String, FriendData> friendsMap = hzInstance.getMultiMap(USER_FRIENDS);
@@ -2130,6 +2272,10 @@ public class MemoryMessagesStore implements IMessagesStore {
@Override
public ErrorCode blackUserRequest(String fromUser, String targetUserId, int state, long[] heads) {
if(state != 0 && state != 1 && state != 2){
return ErrorCode.INVALID_PARAMETER;
}
if (state == 2) {
state = 1;
} else {
@@ -2262,6 +2408,11 @@ public class MemoryMessagesStore implements IMessagesStore {
return true;
}
@Override
public boolean isNewFriendWelcomeMessage() {
return mFriendNewWelcomeMessage;
}
@Override
public ErrorCode deleteFriend(String userId, String friendUid, long[] head) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
@@ -2454,6 +2605,7 @@ public class MemoryMessagesStore implements IMessagesStore {
userGlobalSlientMap.remove(userId);
userConvSlientMap.remove(userId);
userPushHiddenDetail.remove(userId);
IMHandler.getPublisher().publishNotification(IMTopic.NotifyUserSettingTopic, userId, updateDt);
return updateDt;
}
@@ -381,8 +381,8 @@ public class MemorySessionStore implements ISessionsStore {
if (s.getPlatform() == ProtoConstants.Platform.Platform_Android || s.getPlatform() == ProtoConstants.Platform.Platform_iOS) {
remove = true;
}
} else if(platform == ProtoConstants.Platform.Platform_OSX || platform == ProtoConstants.Platform.Platform_Windows || platform == ProtoConstants.Platform.Platform_Linux) {
if (s.getPlatform() == ProtoConstants.Platform.Platform_OSX || s.getPlatform() == ProtoConstants.Platform.Platform_Windows || platform == ProtoConstants.Platform.Platform_Linux) {
} else if(platform == ProtoConstants.Platform.Platform_OSX || platform == ProtoConstants.Platform.Platform_Windows || platform == ProtoConstants.Platform.Platform_LINUX) {
if (s.getPlatform() == ProtoConstants.Platform.Platform_OSX || s.getPlatform() == ProtoConstants.Platform.Platform_Windows || platform == ProtoConstants.Platform.Platform_LINUX) {
remove = true;
}
} else {
@@ -653,6 +653,37 @@ public class MemorySessionStore implements ISessionsStore {
return sessions.get(clientID).secondPhaseStore.size();
}
@Override
public ErrorCode kickoffPCClient(String operator, String pcClientId) {
Session session = sessions.get(pcClientId);
if (session != null) {
if (session.getPlatform() == ProtoConstants.Platform.Platform_LINUX
|| session.getPlatform() == ProtoConstants.Platform.Platform_WEB
|| session.getPlatform() == ProtoConstants.Platform.Platform_Windows
|| session.getPlatform() == ProtoConstants.Platform.Platform_OSX) {
databaseStore.updateSessionDeleted(operator, pcClientId, 1);
sessions.remove(pcClientId);
mServer.getProcessor().kickoffSession(session);
} else {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
}
return ErrorCode.ERROR_CODE_SUCCESS;
}
@Override
public void disableSession(String clientId) {
Session session = sessions.get(clientId);
if (session != null && session.getDeleted() == 0) {
databaseStore.updateSessionDeleted(session.getUsername(), clientId, 1);
ConcurrentSkipListSet<String> sessionSet = getUserSessionSet(session.username);
sessionSet.remove(clientId);
sessions.remove(clientId);
}
}
@Override
public void cleanSession(String clientID) {
LOG.info("Fooooooooo <{}>", clientID);
@@ -680,4 +711,8 @@ public class MemorySessionStore implements ISessionsStore {
// TODO this missing last step breaks the junit test
sessions.remove(clientID);
}
@Override
public boolean isMultiEndpointSupported() {
return supportMultiEndpoint;
}
}
@@ -82,6 +82,8 @@ public class Server {
private ServerAcceptor m_acceptor;
private boolean m_shutdowning = false;
public volatile boolean m_initialized;
private ProtocolProcessor m_processor;
@@ -317,6 +319,12 @@ public class Server {
MediaServerConfig.QINIU_BUCKET_FILE_NAME = config.getProperty(BrokerConstants.QINIU_BUCKET_FILE_NAME);
MediaServerConfig.QINIU_BUCKET_FILE_DOMAIN = config.getProperty(BrokerConstants.QINIU_BUCKET_FILE_DOMAIN);
MediaServerConfig.QINIU_BUCKET_STICKER_NAME = config.getProperty(BrokerConstants.QINIU_BUCKET_STICKER_NAME);
MediaServerConfig.QINIU_BUCKET_STICKER_DOMAIN = config.getProperty(BrokerConstants.QINIU_BUCKET_STICKER_DOMAIN);
MediaServerConfig.QINIU_BUCKET_MOMENTS_NAME = config.getProperty(BrokerConstants.QINIU_BUCKET_MOMENTS_NAME);
MediaServerConfig.QINIU_BUCKET_MOMENTS_DOMAIN = config.getProperty(BrokerConstants.QINIU_BUCKET_MOMENTS_DOMAIN);
MediaServerConfig.QINIU_BUCKET_PORTRAIT_NAME = config.getProperty(BrokerConstants.QINIU_BUCKET_PORTRAIT_NAME);
MediaServerConfig.QINIU_BUCKET_PORTRAIT_DOMAIN = config.getProperty(BrokerConstants.QINIU_BUCKET_PORTRAIT_DOMAIN);
@@ -415,9 +423,15 @@ public class Server {
m_processor.onRpcMsg(fromUser, clientId, message, messageId, from, request, isAdmin);
}
public boolean isShutdowning() {
return m_shutdowning;
}
public void stopServer() {
System.out.println("Server will flush data to db before shutting down, please wait 5 seconds!");
LOG.info("Unbinding server from the configured ports");
m_shutdowning = true;
m_acceptor.close();
LOG.trace("Stopping MQTT protocol processor");
m_processorBootstrapper.shutdown();
@@ -15,6 +15,10 @@ public class MediaServerConfig {
public static String QINIU_BUCKET_VIDEO_DOMAIN;
public static String QINIU_BUCKET_FILE_NAME;
public static String QINIU_BUCKET_FILE_DOMAIN;
public static String QINIU_BUCKET_STICKER_NAME;
public static String QINIU_BUCKET_STICKER_DOMAIN;
public static String QINIU_BUCKET_MOMENTS_NAME;
public static String QINIU_BUCKET_MOMENTS_DOMAIN;
public static String QINIU_BUCKET_PORTRAIT_NAME;
public static String QINIU_BUCKET_PORTRAIT_DOMAIN;
public static String QINIU_BUCKET_FAVORITE_NAME;
@@ -70,7 +70,7 @@ public class NettyMQTTHandler extends ChannelInboundHandlerAdapter {
m_processor.processPubRel(ctx.channel(), msg);
break;
case DISCONNECT:
m_processor.processDisconnect(ctx.channel(), msg.fixedHeader().isDup());
m_processor.processDisconnect(ctx.channel(), msg.fixedHeader().isDup(), msg.fixedHeader().isRetain());
break;
case PUBACK:
m_processor.processPubAck(ctx.channel(), (MqttPubAckMessage) msg);
@@ -109,11 +109,14 @@ public class ClientSession {
}
public void disconnect(boolean cleanSession) {
public void disconnect(boolean cleanSession, boolean disableSession) {
if (cleanSession) {
LOG.info("Client disconnected. Removing its subscriptions. ClientId={}", clientID);
// cleanup topic subscriptions
cleanSession();
} else if(disableSession) {
LOG.info("Client disconnected. disable session. ClientId={}", clientID);
m_sessionsStore.disableSession(this.clientID);
}
}
@@ -122,7 +122,7 @@ public interface IMessagesStore {
boolean isMemberInGroup(String member, String groupId);
ErrorCode canSendMessageInGroup(String member, String groupId);
ErrorCode recallMessage(long messageUid, String operatorId, boolean isAdmin);
ErrorCode recallMessage(long messageUid, String operatorId, String clientId, boolean isAdmin);
void clearUserMessages(String userId);
@@ -131,6 +131,8 @@ public interface IMessagesStore {
ErrorCode getUserInfo(List<WFCMessage.UserRequest> requestList, WFCMessage.PullUserResult.Builder builder);
ErrorCode modifyUserInfo(String userId, WFCMessage.ModifyMyInfoRequest request) throws Exception;
void updateUserOnlineSetting(MemorySessionStore.Session session, boolean online);
ErrorCode modifyUserStatus(String userId, int status);
int getUserStatus(String userId);
List<InputOutputUserBlockStatus> getUserStatusList();
@@ -157,7 +159,6 @@ public interface IMessagesStore {
WFCMessage.PullMessageResult fetchChatroomMessage(String fromUser, String chatroomId, String exceptClientId, long fromMessageId);
ErrorCode verifyToken(String userId, String token, List<String> serverIPs, List<Integer> ports);
ErrorCode login(String name, String password, List<String> userIdRet);
List<FriendData> getFriendList(String userId, String clientId, long version);
void clearUserFriend(String userId);
@@ -165,6 +166,7 @@ public interface IMessagesStore {
ErrorCode saveAddFriendRequest(String userId, WFCMessage.AddFriendRequest request, long[] head);
ErrorCode handleFriendRequest(String userId, WFCMessage.HandleFriendRequest request, WFCMessage.Message.Builder msgBuilder, long[] heads, boolean isAdmin);
boolean isNewFriendWelcomeMessage();
ErrorCode deleteFriend(String userId, String friendUid, long[] head);
ErrorCode blackUserRequest(String fromUser, String targetUserId, int status, long[] head);
FriendData getFriendData(String fromUser, String targetUserId);
@@ -148,5 +148,10 @@ public interface ISessionsStore {
*/
int getSecondPhaseAckPendingMessages(String clientID);
void disableSession(String clientId);
void cleanSession(String clientID);
boolean isMultiEndpointSupported();
ErrorCode kickoffPCClient(String operator, String pcClientId);
}
@@ -16,6 +16,7 @@
package io.moquette.spi.impl;
import cn.wildfirechat.pojos.OutputMessageData;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
import cn.wildfirechat.push.PushServer;
@@ -158,7 +159,7 @@ public class MessagesPublisher {
}
}
private void publish2Receivers(String sender, int conversationType, String target, int line, long messageHead, Collection<String> receivers, String pushContent, String exceptClientId, int pullType, int messageContentType, long serverTime, int mentionType, List<String> mentionTargets, int persistFlag) {
private void publish2Receivers(String sender, int conversationType, String target, int line, long messageHead, Collection<String> receivers, String pushContent, String pushData, String exceptClientId, int pullType, int messageContentType, long serverTime, int mentionType, List<String> mentionTargets, int persistFlag) {
if (persistFlag == Transparent) {
publishTransparentMessage2Receivers(messageHead, receivers, pullType);
return;
@@ -252,8 +253,8 @@ public class MessagesPublisher {
}
}
if (!StringUtil.isNullOrEmpty(pushContent) || messageContentType == 400 || messageContentType == 402) {
if (!isSlient) {
if (!StringUtil.isNullOrEmpty(pushContent) || messageContentType == 400) {
if (!isSlient && (persistFlag & 0x02) > 0) {
targetSession.setUnReceivedMsgs(targetSession.getUnReceivedMsgs() + 1);
}
}
@@ -331,7 +332,7 @@ public class MessagesPublisher {
name = fd.getAlias();
}
}
this.messageSender.sendPush(sender, conversationType, target, line, messageHead, targetSession.getClientID(), pushContent, messageContentType, serverTime, name, targetName, targetSession.getUnReceivedMsgs(), curMentionType, isHiddenDetail, targetSession.getLanguage());
this.messageSender.sendPush(sender, conversationType, target, line, messageHead, targetSession.getClientID(), pushContent, pushData, messageContentType, serverTime, name, targetName, targetSession.getUnReceivedMsgs(), curMentionType, isHiddenDetail, targetSession.getLanguage());
}
}
@@ -544,12 +545,12 @@ public class MessagesPublisher {
message.getConversation().getType(), message.getConversation().getTarget(), message.getConversation().getLine(),
messageId,
receivers,
pushContent, exceptClientId, pullType, message.getContent().getType(), message.getServerTimestamp(), message.getContent().getMentionedType(), message.getContent().getMentionedTargetList(), message.getContent().getPersistFlag());
pushContent, message.getContent().getPushData(), exceptClientId, pullType, message.getContent().getType(), message.getServerTimestamp(), message.getContent().getMentionedType(), message.getContent().getMentionedTargetList(), message.getContent().getPersistFlag());
}
public void forwardMessage(final WFCMessage.Message message, String forwardUrl) {
executorCallback.execute(() -> HttpUtils.httpJsonPost(forwardUrl, new Gson().toJson(SendMessageData.fromProtoMessage(message), SendMessageData.class)));
executorCallback.execute(() -> HttpUtils.httpJsonPost(forwardUrl, new Gson().toJson(OutputMessageData.fromProtoMessage(message), OutputMessageData.class)));
}
public void notifyChannelListenStatusChanged(WFCMessage.ChannelInfo channelInfo, String user, boolean listen) {
@@ -37,10 +37,11 @@ class PersistentQueueMessageSender {
this.connectionDescriptorStore = connectionDescriptorStore;
}
void sendPush(String sender, int conversationType, String target, int line, long messageHead, String deviceId, String pushContent, int messageContentType, long serverTime, String senderName, String targetName, int unReceivedMsg, int mentionType, boolean isHiddenDetail, String language) {
void sendPush(String sender, int conversationType, String target, int line, long messageHead, String deviceId, String pushContent, String pushData, int messageContentType, long serverTime, String senderName, String targetName, int unReceivedMsg, int mentionType, boolean isHiddenDetail, String language) {
LOG.info("Send push to {}, message from {}", deviceId, sender);
PushMessage pushMessage = new PushMessage(sender, conversationType, target, line, messageContentType, serverTime, senderName, targetName, unReceivedMsg, mentionType, isHiddenDetail, language);
pushMessage.pushContent = pushContent;
pushMessage.pushData = pushData;
PushServer.getServer().pushMessage(pushMessage, deviceId, pushContent);
}
@@ -75,7 +75,7 @@ public class ProtocolProcessor {
ConnectionDescriptor descriptor = connectionDescriptors.getConnection(session.getClientID());
try {
if (descriptor != null) {
processDisconnect(descriptor.getChannel(), true);
processDisconnect(descriptor.getChannel(), true, false);
}
} catch (InterruptedException e) {
e.printStackTrace();
@@ -92,7 +92,7 @@ public class ProtocolProcessor {
ConnectionDescriptor descriptor = connectionDescriptors.getConnection(session.getClientID());
try {
if (descriptor != null) {
processDisconnect(descriptor.getChannel(), true);
processDisconnect(descriptor.getChannel(), true, false);
}
} catch (InterruptedException e) {
e.printStackTrace();
@@ -244,6 +244,7 @@ public class ProtocolProcessor {
if(session != null) {
session.refreshLastActiveTime();
forwardOnlineStatusEvent(payload.userName(), clientId, session.getPlatform(), UserOnlineStatus.ONLINE);
m_messagesStore.updateUserOnlineSetting(session, true);
} else {
forwardOnlineStatusEvent(payload.userName(), clientId, ProtoConstants.Platform.Platform_UNSET, UserOnlineStatus.ONLINE);
}
@@ -504,19 +505,19 @@ public class ProtocolProcessor {
//not use
}
public void processDisconnect(Channel channel, boolean clearSession) throws InterruptedException {
public void processDisconnect(Channel channel, boolean isDup, boolean isRetain) throws InterruptedException {
final String clientID = NettyUtils.clientID(channel);
LOG.info("Processing DISCONNECT message. CId={}, clearSession={}", clientID, clearSession);
LOG.info("Processing DISCONNECT message. CId={}, clearSession={}", clientID, isDup);
channel.flush();
if (clientID == null) {
LOG.error("Error. Cid not exist!!!", clientID, clearSession);
LOG.error("Error. Cid not exist!!!", clientID, isDup);
channel.close();
return;
}
if (!clearSession) {
processConnectionLost(clientID, channel, clearSession);
if (!isDup && !isRetain) {
processConnectionLost(clientID, channel, isDup);
return;
}
@@ -559,6 +560,9 @@ public class ProtocolProcessor {
String username = NettyUtils.userName(channel);
MemorySessionStore.Session session = m_sessionsStore.getSession(clientID);
if(session != null) {
m_messagesStore.updateUserOnlineSetting(session, false);
}
if(session != null) {
forwardOnlineStatusEvent(username, clientID, session.getPlatform(), UserOnlineStatus.LOGOUT);
}
@@ -567,7 +571,7 @@ public class ProtocolProcessor {
//disconnect the session
m_sessionsStore.sessionForClient(clientID).disconnect(clearSession);
m_sessionsStore.sessionForClient(clientID).disconnect(isDup, isRetain);
}
@@ -605,6 +609,7 @@ public class ProtocolProcessor {
if(session != null) {
session.refreshLastActiveTime();
forwardOnlineStatusEvent(username, clientID, session.getPlatform(), clearSession ? UserOnlineStatus.LOGOUT : UserOnlineStatus.OFFLINE);
m_messagesStore.updateUserOnlineSetting(session, false);
}
ConnectionDescriptor oldConnDescr = new ConnectionDescriptor(clientID, channel);
@@ -80,12 +80,10 @@ public class DBUtil {
comboPooledDataSource = new ComboPooledDataSource("mysql");
try {
String url01 = comboPooledDataSource.getJdbcUrl().substring(0,comboPooledDataSource.getJdbcUrl().indexOf("?"));
String url02 = url01.substring(0,url01.lastIndexOf("/"));
String datasourceName = url01.substring(url01.lastIndexOf("/")+1);
// 连接已经存在的数据库,如:mysql
Connection connection = DriverManager.getConnection(url02, comboPooledDataSource.getUser(), comboPooledDataSource.getPassword());
String jdbc = comboPooledDataSource.getJdbcUrl().replace(datasourceName, "");
Connection connection = DriverManager.getConnection(jdbc, comboPooledDataSource.getUser(), comboPooledDataSource.getPassword());
Statement statement = connection.createStatement();
// 创建数据库
@@ -74,4 +74,5 @@ public interface IMTopic {
String DestroyUserTopic = "DESTROYUSER";
String LoadRemoteMessagesTopic = "LRM";
String KickoffPCClientTopic = "KPCC";
}
@@ -64,6 +64,10 @@ public class MessageBundle implements Serializable {
return message;
}
public void setFromClientId(String fromClientId) {
this.fromClientId = fromClientId;
}
public void setMessage(WFCMessage.Message message) {
this.fromUser = message.getFromUser();
this.type = message.getConversation().getType();
@@ -13,7 +13,7 @@ import java.util.Date;
public class MessageShardingUtil {
private static SpinLock mLock = new SpinLock();
private static int rotateId = 0;
private static volatile int rotateId = 0;
private static int nodeId = 0;
private static int rotateIdWidth = 15;
@@ -11,6 +11,7 @@ public interface UserSettingScope {
int kUserSettingConversationSync = 7;
int kUserSettingMyChannels = 8;
int kUserSettingListenedChannels = 9;
int kUserSettingPCOnline = 10;
int kUserSettingCustomBegin = 1000;
}
+1 -1
View File
@@ -18,7 +18,7 @@
<!--MySQL数据库驱动程序-->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<!--MySQL数据库地址-->
<property name="jdbcUrl">jdbc:mysql://localhost:3306/wfchat?useSSL=false&amp;serverTimezone=GMT%2B8&amp;allowPublicKeyRetrieval=true&amp;useUnicode=true&amp;characterEncoding=utf8</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/wfchat?verifyServerCertificate=false&amp;useSSL=false&amp;serverTimezone=GMT%2B8&amp;allowPublicKeyRetrieval=true&amp;useUnicode=true&amp;characterEncoding=UTF-8</property>
<!--MySQL数据库用户名-->
<property name="user">root</property>
<!--MySQL数据库密码-->
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.39</version>
<version>0.43</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -5,6 +5,11 @@ public interface APIPath {
String Chatroom_Destroy = "/admin/chatroom/del";
String Chatroom_Info = "/admin/chatroom/info";
String Chatroom_GetMembers = "/admin/chatroom/members";
String Chatroom_SetBlacklist = "/admin/chatroom/set_black_status";
String Chatroom_GetBlacklist = "/admin/chatroom/get_black_status";
String Chatroom_SetManager = "/admin/chatroom/set_manager";
String Chatroom_GetManagerList = "/admin/chatroom/get_manager_list";
String Chatroom_MuteAll = "/admin/chatroom/mute_all";
String Sensitive_Add = "/admin/sensitive/add";
@@ -14,6 +19,9 @@ public interface APIPath {
String Create_User = "/admin/user/create";
String Destroy_User = "/admin/user/destroy";
String Create_Robot = "/admin/robot/create";
String CreateOrUpdate_Device = "/admin/device/create";
String Get_Device = "/admin/device/get";
String Get_User_Devices = "/admin/device/user_devices";
String User_Get_Token = "/admin/user/get_token";
String User_Update_Block_Status = "/admin/user/update_block_status";
String User_Get_Info = "/admin/user/get_info";
@@ -31,6 +39,7 @@ public interface APIPath {
String Msg_Send = "/admin/message/send";
String Msg_Recall = "/admin/message/recall";
String Msg_Delete = "/admin/message/delete";
String Msg_Broadcast = "/admin/message/broadcast";
String Msg_Multicast = "/admin/message/multicast";
@@ -44,6 +53,7 @@ public interface APIPath {
String Group_Member_Kickoff = "/admin/group/member/del";
String Group_Member_Quit = "/admin/group/member/quit";
String Group_Set_Manager = "/admin/group/manager/set";
String Group_Mute_Member = "/admin/group/manager/mute";
String Get_User_Groups = "/admin/group/of_user";
@@ -29,10 +29,6 @@ public enum ErrorCode {
//Group error
ERROR_CODE_GROUP_ALREADY_EXIST(11, "group aleady exist"),
//user error
ERROR_CODE_PASSWORD_INCORRECT(15, "password incorrect"),
//user error
ERROR_CODE_FRIEND_ALREADY_REQUEST(16, "already send request"),
ERROR_CODE_FRIEND_REQUEST_BLOCKED(18, "friend request blocked"),
@@ -42,6 +38,9 @@ public enum ErrorCode {
ERROR_CODE_NOT_IN_CHANNEL(21, "not in channel"),
ERROR_CODE_ALREADY_FRIENDS(23, "already friends"),
ERROR_CODE_GROUP_EXCEED_MAX_MEMBER_COUNT(240, "group exceed max member count"),
ERROR_CODE_GROUP_MUTED(241, "group is muted"),
ERROR_CODE_SENSITIVE_MATCHED(242, "sensitive matched"),
ERROR_CODE_SIGN_EXPIRED(243, "sign expired"),
@@ -0,0 +1,21 @@
/*
* 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 DeleteMessageData {
private long messageUid;
public long getMessageUid() {
return messageUid;
}
public void setMessageUid(long messageUid) {
this.messageUid = messageUid;
}
}
@@ -0,0 +1,50 @@
/*
* 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;
import cn.wildfirechat.proto.WFCMessage;
import io.netty.util.internal.StringUtil;
import java.util.List;
public class ForwardDeviceMessageData {
private String deviceId;
private int type;
private byte[] data;
public ForwardDeviceMessageData(String deviceId, int type, byte[] data) {
this.deviceId = deviceId;
this.type = type;
this.data = data;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
}
@@ -145,6 +145,8 @@ public class GroupNotificationBinaryContent {
return getGroupNotifyContent(ProtoConstants.MESSAGE_CONTENT_TYPE_SET_MANAGER);
}
public WFCMessage.MessageContent getMuteGroupMemberNotifyContent() {
return getGroupNotifyContent(ProtoConstants.MESSAGE_CONTENT_TYPE_MUTE_MEMBER);
}
}
@@ -0,0 +1,12 @@
package cn.wildfirechat.pojos;
public class InputChatroomId {
public String chatroomId;
public InputChatroomId() {
}
public InputChatroomId(String chatroomId) {
this.chatroomId = chatroomId;
}
}
@@ -0,0 +1,36 @@
/*
* 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 InputChatroomMute {
private String chatroomId;
private int status;
public InputChatroomMute(String chatroomId, int status) {
this.chatroomId = chatroomId;
this.status = status;
}
public String getChatroomId() {
return chatroomId;
}
public void setChatroomId(String chatroomId) {
this.chatroomId = chatroomId;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
@@ -0,0 +1,45 @@
/*
* 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;
import cn.wildfirechat.proto.WFCMessage;
import io.netty.util.internal.StringUtil;
import java.util.List;
public class InputCreateDevice {
private String deviceId;
private List<String> owners;
private String extra;
public List<String> getOwners() {
return owners;
}
public void setOwners(List<String> owners) {
this.owners = owners;
}
public String getExtra() {
return extra;
}
public void setExtra(String extra) {
this.extra = extra;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
}
@@ -24,27 +24,41 @@ public class InputCreateGroup extends InputGroupBase {
public WFCMessage.CreateGroupRequest toProtoGroupRequest() {
WFCMessage.Group.Builder groupBuilder = WFCMessage.Group.newBuilder();
WFCMessage.GroupInfo.Builder groupInfoBuilder = WFCMessage.GroupInfo.newBuilder();
if (!StringUtil.isNullOrEmpty(group.getGroup_info().target_id)) {
groupInfoBuilder.setTargetId(group.getGroup_info().getTarget_id());
PojoGroupInfo group_info = group.getGroup_info();
if (!StringUtil.isNullOrEmpty(group_info.target_id)) {
groupInfoBuilder.setTargetId(group_info.getTarget_id());
}
if (!StringUtil.isNullOrEmpty(group.getGroup_info().name)) {
groupInfoBuilder.setName(group.getGroup_info().getName());
if (!StringUtil.isNullOrEmpty(group_info.name)) {
groupInfoBuilder.setName(group_info.getName());
}
if (!StringUtil.isNullOrEmpty(group.getGroup_info().portrait)) {
groupInfoBuilder.setPortrait(group.getGroup_info().getPortrait());
if (!StringUtil.isNullOrEmpty(group_info.portrait)) {
groupInfoBuilder.setPortrait(group_info.getPortrait());
}
if (!StringUtil.isNullOrEmpty(group.getGroup_info().owner)) {
groupInfoBuilder.setOwner(group.getGroup_info().getOwner());
if (!StringUtil.isNullOrEmpty(group_info.owner)) {
groupInfoBuilder.setOwner(group_info.getOwner());
}
groupInfoBuilder.setType(group.getGroup_info().getType());
groupInfoBuilder.setType(group_info.getType());
if (!StringUtil.isNullOrEmpty(group.getGroup_info().extra)) {
groupInfoBuilder.setExtra(group.getGroup_info().getExtra());
if (!StringUtil.isNullOrEmpty(group_info.extra)) {
groupInfoBuilder.setExtra(group_info.getExtra());
}
if (group_info.join_type > 0 && group_info.join_type < 128) {
groupInfoBuilder.setJoinType(group_info.join_type);
}
if (group_info.mute > 0 && group_info.mute < 128) {
groupInfoBuilder.setMute(group_info.mute);
}
if (group_info.private_chat > 0 && group_info.private_chat < 128) {
groupInfoBuilder.setPrivateChat(group_info.private_chat);
}
if (group_info.searchable > 0) {
groupInfoBuilder.setSearchable(group_info.searchable);
}
groupBuilder.setGroupInfo(groupInfoBuilder);
for (PojoGroupMember pojoGroupMember : group.getMembers()) {
@@ -0,0 +1,21 @@
/*
* 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 InputDeviceId {
private String deviceId;
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
}
@@ -0,0 +1,72 @@
/*
* 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;
import cn.wildfirechat.proto.WFCMessage;
import io.netty.util.internal.StringUtil;
import java.util.List;
public class InputMuteGroupMember extends InputGroupBase {
private String group_id;
private List<String> members;
private boolean is_manager;
public String getGroup_id() {
return group_id;
}
public void setGroup_id(String group_id) {
this.group_id = group_id;
}
public List<String> getMembers() {
return members;
}
public void setMembers(List<String> members) {
this.members = members;
}
public boolean isIs_manager() {
return is_manager;
}
public void setIs_manager(boolean is_manager) {
this.is_manager = is_manager;
}
public boolean isValide() {
if (StringUtil.isNullOrEmpty(operator) || StringUtil.isNullOrEmpty(group_id) || members == null || members.isEmpty()) {
return false;
}
return true;
}
public WFCMessage.SetGroupManagerRequest toProtoGroupRequest() {
WFCMessage.SetGroupManagerRequest.Builder addGroupBuilder = WFCMessage.SetGroupManagerRequest.newBuilder();
addGroupBuilder.setGroupId(group_id);
addGroupBuilder.addAllUserId(members);
addGroupBuilder.setType(is_manager ? 1 : 0);
if (to_lines != null) {
for (Integer line : to_lines
) {
addGroupBuilder.addToLine(line);
}
}
if (notify_message != null) {
addGroupBuilder.setNotifyContent(notify_message.toProtoMessageContent());
}
return addGroupBuilder.build();
}
}
@@ -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 InputSetChatroomBlacklist {
private String chatroomId;
private String userId;
private int status;
private long expiredTime;
public InputSetChatroomBlacklist() {
}
public InputSetChatroomBlacklist(String chatroomId, String userId, int status, long expiredTime) {
this.chatroomId = chatroomId;
this.userId = userId;
this.status = status;
this.expiredTime = expiredTime;
}
public String getChatroomId() {
return chatroomId;
}
public void setChatroomId(String chatroomId) {
this.chatroomId = chatroomId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public long getExpiredTime() {
return expiredTime;
}
public void setExpiredTime(long expiredTime) {
this.expiredTime = expiredTime;
}
}
@@ -0,0 +1,48 @@
/*
* 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 InputSetChatroomManager {
private String chatroomId;
private String userId;
private int status;
public InputSetChatroomManager() {
}
public InputSetChatroomManager(String chatroomId, String userId, int status) {
this.chatroomId = chatroomId;
this.userId = userId;
this.status = status;
}
public String getChatroomId() {
return chatroomId;
}
public void setChatroomId(String chatroomId) {
this.chatroomId = chatroomId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
@@ -20,6 +20,7 @@ public class MessagePayload {
private int type;
private String searchableContent;
private String pushContent;
private String pushData;
private String content;
private String base64edData;
private int mediaType;
@@ -28,6 +29,8 @@ public class MessagePayload {
private int expireDuration;
private int mentionedType;
private List<String> mentionedTarget;
private String extra;
public int getType() {
return type;
@@ -117,6 +120,22 @@ public class MessagePayload {
this.mentionedTarget = mentionedTarget;
}
public String getExtra() {
return extra;
}
public void setExtra(String extra) {
this.extra = extra;
}
public String getPushData() {
return pushData;
}
public void setPushData(String pushData) {
this.pushData = pushData;
}
public WFCMessage.MessageContent toProtoMessageContent() {
WFCMessage.MessageContent.Builder builder = WFCMessage.MessageContent.newBuilder()
.setType(type)
@@ -137,6 +156,10 @@ public class MessagePayload {
builder.setRemoteMediaUrl(remoteMediaUrl);
if (mentionedTarget != null && mentionedTarget.size() > 0)
builder.addAllMentionedTarget(mentionedTarget);
if (!StringUtil.isNullOrEmpty(extra))
builder.setExtra(extra);
if (!StringUtil.isNullOrEmpty(pushData))
builder.setPushData(pushData);
return builder.build();
}
@@ -159,6 +182,8 @@ public class MessagePayload {
payload.mentionedType = protoContent.getMentionedType();
payload.mentionedTarget = new ArrayList<>();
payload.mentionedTarget.addAll(protoContent.getMentionedTargetList());
payload.extra = protoContent.getExtra();
payload.pushData = protoContent.getPushData();
return payload;
}
}
@@ -0,0 +1,25 @@
package cn.wildfirechat.pojos;
import java.util.ArrayList;
import java.util.List;
public class OutputChatroomBlackInfos {
public static class OutputChatroomBlackInfo {
public String userId;
public int state;
public long expiredTime;
public OutputChatroomBlackInfo() {
}
public OutputChatroomBlackInfo(String userId, int state, long expiredTime) {
this.userId = userId;
this.state = state;
this.expiredTime = expiredTime;
}
}
public List<OutputChatroomBlackInfo> infos = new ArrayList<>();
public void addBlackInfo(String userId, int state, long expiredTime) {
infos.add(new OutputChatroomBlackInfo(userId, state, expiredTime));
}
}
@@ -0,0 +1,45 @@
/*
* 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 OutputCreateDevice {
private String deviceId;
private String token;
private String secret;
public OutputCreateDevice(String userId, String token, String secret) {
this.deviceId = userId;
this.token = token;
this.secret = secret;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
}
@@ -0,0 +1,76 @@
/*
* 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;
import cn.wildfirechat.proto.WFCMessage;
import java.util.List;
public class OutputDevice {
private int state;
private String deviceId;
private String token;
private String secret;
private List<String> owners;
private String extra;
public OutputDevice(String deviceId, String token, String secret) {
this.deviceId = deviceId;
this.token = token;
this.secret = secret;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public List<String> getOwners() {
return owners;
}
public void setOwners(List<String> owners) {
this.owners = owners;
}
public String getExtra() {
return extra;
}
public void setExtra(String extra) {
this.extra = extra;
}
}
@@ -0,0 +1,23 @@
/*
* 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;
import java.util.List;
public class OutputDeviceHost {
private String host;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
}
@@ -0,0 +1,23 @@
/*
* 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;
import java.util.List;
public class OutputDeviceList {
private List<OutputDevice> devices;
public List<OutputDevice> getDevices() {
return devices;
}
public void setDevices(List<OutputDevice> devices) {
this.devices = devices;
}
}
@@ -0,0 +1,85 @@
/*
* 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;
import cn.wildfirechat.proto.WFCMessage;
import io.netty.util.internal.StringUtil;
import java.util.List;
public class OutputMessageData {
private long messageId;
private String sender;
private Conversation conv;
private MessagePayload payload;
private List<String> toUsers;
private long timestamp;
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public Conversation getConv() {
return conv;
}
public void setConv(Conversation conv) {
this.conv = conv;
}
public MessagePayload getPayload() {
return payload;
}
public void setPayload(MessagePayload payload) {
this.payload = payload;
}
public List<String> getToUsers() {
return toUsers;
}
public void setToUsers(List<String> toUsers) {
this.toUsers = toUsers;
}
public long getMessageId() {
return messageId;
}
public void setMessageId(long messageId) {
this.messageId = messageId;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public static OutputMessageData fromProtoMessage(WFCMessage.Message protoMessage) {
OutputMessageData data = new OutputMessageData();
data.messageId = protoMessage.getMessageId();
data.sender = protoMessage.getFromUser();
data.conv = new Conversation();
data.conv.setTarget(protoMessage.getConversation().getTarget());
data.conv.setType(protoMessage.getConversation().getType());
data.conv.setLine(protoMessage.getConversation().getLine());
data.payload = MessagePayload.fromProtoMessageContent(protoMessage.getContent());
data.timestamp = protoMessage.getServerTimestamp();
data.toUsers = protoMessage.getToList();
return data;
}
}
@@ -15,6 +15,12 @@ public class PojoGroupInfo {
String owner;
int type;
String extra;
int mute;
int join_type;
int private_chat;
int searchable;
int max_member_count;
int history_message;
public String getTarget_id() {
return target_id;
@@ -63,4 +69,52 @@ public class PojoGroupInfo {
public void setExtra(String extra) {
this.extra = extra;
}
public int getMax_member_count() {
return max_member_count;
}
public void setMax_member_count(int max_member_count) {
this.max_member_count = max_member_count;
}
public int getMute() {
return mute;
}
public void setMute(int mute) {
this.mute = mute;
}
public int getJoin_type() {
return join_type;
}
public void setJoin_type(int join_type) {
this.join_type = join_type;
}
public int getPrivate_chat() {
return private_chat;
}
public void setPrivate_chat(int private_chat) {
this.private_chat = private_chat;
}
public int getSearchable() {
return searchable;
}
public void setSearchable(int searchable) {
this.searchable = searchable;
}
public int getHistory_message() {
return history_message;
}
public void setHistory_message(int history_message) {
this.history_message = history_message;
}
}
@@ -8,7 +8,7 @@ public class ProtoConstants {
int ConversationType_Group = 1;
int ConversationType_ChatRoom = 2;
int ConversationType_Channel = 3;
int ConversationType_Thing = 4;
int ConversationType_Things = 4;
}
//message GroupInfo -> type
@@ -46,7 +46,7 @@ public class ProtoConstants {
int Platform_OSX = 4;
int Platform_WEB = 5;
int Platform_WX = 6;
int Platform_Linux = 7;
int Platform_LINUX = 7;
}
//message NotifyMessage & PullMessageRequest -> type
@@ -181,5 +181,6 @@ public class ProtoConstants {
public static final int MESSAGE_CONTENT_TYPE_CHANGE_SEARCHABLE = 116;
public static final int MESSAGE_CONTENT_TYPE_SET_MANAGER = 117;
public static final int MESSAGE_CONTENT_TYPE_MUTE_MEMBER = 118;
}
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -6,7 +6,7 @@
<!--<relativePath>../pom.xml</relativePath>-->
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.39</version>
<version>0.43</version>
</parent>
<artifactId>distribution</artifactId>
@@ -15,7 +15,7 @@
<!--MySQL数据库驱动程序-->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<!--MySQL数据库地址-->
<property name="jdbcUrl">jdbc:mysql://localhost:3306/wfchat?useSSL=false&amp;serverTimezone=GMT%2B8&amp;allowPublicKeyRetrieval=true&amp;useUnicode=true&amp;characterEncoding=utf8</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/wfchat?useSSL=false&amp;serverTimezone=GMT%2B8&amp;allowPublicKeyRetrieval=true&amp;useUnicode=true&amp;characterEncoding=UTF-8</property>
<!--MySQL数据库用户名-->
<property name="user">root</property>
<!--MySQL数据库密码-->
@@ -41,7 +41,7 @@
<!--关闭连接时,是否提交未提交的事务,默认为false,即关闭连接,回滚未提交的事务 -->
<property name="autoCommitOnClose">false</property>
<!--c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试使用。默认值: null -->
<property name="automaticTestTable">Test</property>
<!-- <property name="automaticTestTable">Test</property>-->
<!--如果为false,则获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常,但是数据源仍有效保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试获取连接失败后该数据源将申明已断开并永久关闭。默认: false-->
<property name="breakAfterAcquireFailure">false</property>
<!--每60秒检查所有连接池中的空闲连接。默认值: 0,不检查 -->
+18 -2
View File
@@ -84,6 +84,12 @@
<map name="user_chatroom">
</map>
<multimap name="chatroom_black">
</multimap>
<multimap name="chatroom_manager">
</multimap>
<map name="robots">
<!-- 7 days -->
<time-to-live-seconds>604800</time-to-live-seconds>
@@ -96,13 +102,23 @@
</map-store>
</map>
<map name="things">
<map name="devices">
<!-- 7 days -->
<time-to-live-seconds>604800</time-to-live-seconds>
<eviction-policy>LRU</eviction-policy>
<max-size policy="PER_NODE">1000000</max-size>
<eviction-percentage>10</eviction-percentage>
<map-store enabled="true">
<class-name>io.moquette.persistence.DeviceLoader</class-name>
<write-delay-seconds>0</write-delay-seconds>
</map-store>
</map>
<multimap name="user_robots">
</multimap>
<multimap name="user_things">
<multimap name="user_devices">
</multimap>
@@ -46,10 +46,12 @@ token.key testim
##token的过期时间,单位为毫秒,默认为无限期。如果需要设置无限期,客户端上一定需要加上token过期的处理。token过期的处理请参考文档的常见问题
##token.expire_time 2592000000
##首次登录,是否接收之前的历史消息。0 不接收;1接收。
##首次登录,是否接收之前的历史消息。
##0 不接收历史消息,只接收5分钟以内的消息,由于服务器没有保存已经收取记录,所以如果有超过5分钟之前未收取的消息也不会收取下拉;
##1接收,会接收 message.max_queue 配置的条数的历史消息
message.roaming 0
##是否开启拉取远程历史消息
##是否开启拉取远程历史消息。如果为1,客户端在会话内如果本地消息读取完了,可以下拉继续加载在服务器上的该会话的消息;如果为0则不能。
message.remote_history_message 0
##服务器为每个用户缓存的消息数量。这个值改得太大,拉取消息时间变长,另外会占用大量内存。
@@ -58,9 +60,22 @@ message.max_queue 1024
##是否禁止陌生人聊天
message.disable_stranger_chat false
##黑名单处理策略,0 发送失败,返回被拉黑的错误码;1 发送成功但消息被服务器直接丢弃;
##黑名单处理策略,0 发送失败,返回被拉黑的错误码;1 发送成功但消息被服务器直接丢弃;2 敏感词替换为***;3 不处理。
##所有命中敏感词的消息都会被记录在敏感词消息表中
message.blacklist.strategy 0
##是否禁止服务器端消息搜索,该功能暂未实现。目前的影响是如果打开,则存储消息时不单独保存_searchable_content字段
message.disable_remote_search false
##禁止搜索用户
friend.disable_search false
##禁止按照昵称搜索用户。
friend.disable_nick_name_search false
##禁止发送好友邀请,通过server api添加好友不受此限制
friend.disable_friend_request false
##好友请求重复发送的间隔,单位是毫秒,默认是7天,0为不限制
friend.repeat_request_duration 604800000
@@ -70,6 +85,12 @@ friend.reject_request_duration 2592000000
##好友请求过期时间,单位是毫秒,默认是7天,0为不限制
friend.request_expiration_duration 604800000
##添加好友后会发送欢迎消息,比如"你们已经是好友了,可以聊天了"。这个开关控制是用旧的方式还是用新的方式。
##旧的方式会发送notification消息(contenttype是80),内容会根据好友接收者的语言选择对应的语言,如果双方语言不一致会导致另外一方看到的不是本地语言。
##新的方式会发送添加好友消息(contenttype是93)和欢迎消息(contenttype是92),需要客户端实现这两种消息。
##如果客户端已经实现这两种消息可以打开这个开关
friend.new_welcome_message false
## 聊天室观众空闲退出时间,单位为毫秒,默认为15分钟,0为永远不退出
chatroom.participant_idle_time 900000
@@ -112,6 +133,10 @@ qiniu.bucket_video_name media
qiniu.bucket_video_domain http://cdn.wildfirechat.cn
qiniu.bucket_file_name media
qiniu.bucket_file_domain http://cdn.wildfirechat.cn
qiniu.bucket_sticker_name media
qiniu.bucket_sticker_domain http://cdn.wildfirechat.cn
qiniu.bucket_moments_name media
qiniu.bucket_moments_domain http://cdn.wildfirechat.cn
qiniu.bucket_portrait_name storage
qiniu.bucket_portrait_domain http://cdn2.wildfirechat.cn
qiniu.bucket_favorite_name storage
@@ -123,9 +148,12 @@ qiniu.bucket_favorite_domain http://cdn2.wildfirechat.cn
local.media.storage.root ./media
# 是否支持多端登陆
# 是否支持多端登陆,为true时支持任意平台任意多个客户端同时登录;为false时每个平台只支持一个端登录,但不同平台可以同时登录。
server.multi_endpoint false
# 多平台连接状态通知(仅当multi_endpoint为false时有效),true时移动端可以收到pc或web端登录的通知。
server.multi_platform_notification false
#*********************************************************************
# Push server configuration
#*********************************************************************
@@ -173,3 +201,6 @@ sensitive.filter.type 0
#*********************************************************************
##消息转发地址
#message.forward.url http://localhost:8087/message/forward
##设备信息转发地址
#device.forward.url http://localhost:8087/device/forward
+1 -1
View File
@@ -12,7 +12,7 @@
<artifactId>wildfirechat-parent</artifactId>
<packaging>pom</packaging>
<version>0.39</version>
<version>0.43</version>
<name>Wildfire Chat</name>
<description>Wildfire Chat Server</description>
<inceptionYear>2019</inceptionYear>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.39</version>
<version>0.43</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -37,6 +37,37 @@ public class ChatroomAdmin {
return AdminHttpUtils.httpJsonPost(path, input, OutputStringList.class);
}
//仅专业版支持
//status:0,正常;1,禁言;2,禁止加入
public static IMResult<Void> setChatroomBlacklist(String chatroomId, String userId, int status) throws Exception {
String path = APIPath.Chatroom_SetBlacklist;
InputSetChatroomBlacklist input = new InputSetChatroomBlacklist(chatroomId, userId, status, 0);
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
}
public static IMResult<OutputChatroomBlackInfos> getChatroomBlacklist(String chatroomId) throws Exception {
String path = APIPath.Chatroom_GetBlacklist;
InputChatroomId input = new InputChatroomId(chatroomId);
return AdminHttpUtils.httpJsonPost(path, input, OutputChatroomBlackInfos.class);
}
//status: 1 set; 0 unset
public static IMResult<Void> setChatroomManager(String chatroomId, String userId, int status) throws Exception {
String path = APIPath.Chatroom_SetManager;
InputSetChatroomManager input = new InputSetChatroomManager(chatroomId, userId, status);
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
}
public static IMResult<OutputStringList> getChatroomManagerList(String chatroomId) throws Exception {
String path = APIPath.Chatroom_GetManagerList;
InputChatroomId input = new InputChatroomId(chatroomId);
return AdminHttpUtils.httpJsonPost(path, input, OutputStringList.class);
}
public static IMResult<Void> setChatroomMute(String chatroomId, boolean mute) throws Exception {
String path = APIPath.Chatroom_MuteAll;
InputChatroomMute input = new InputChatroomMute(chatroomId, mute ? 1 : 0);
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
}
}
@@ -52,7 +52,7 @@ public class GroupAdmin {
return AdminHttpUtils.httpJsonPost(path, transferGroup, Void.class);
}
public static IMResult<Void> modifyGroupInfo(String operator, String groupId, int type, String value, List<Integer> to_lines) throws Exception {
public static IMResult<Void> modifyGroupInfo(String operator, String groupId, /*ModifyGroupInfoType*/int type, String value, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
String path = APIPath.Group_Modify_Info;
InputModifyGroupInfo modifyGroupInfo = new InputModifyGroupInfo();
modifyGroupInfo.setGroup_id(groupId);
@@ -60,6 +60,7 @@ public class GroupAdmin {
modifyGroupInfo.setTo_lines(to_lines);
modifyGroupInfo.setType(type);
modifyGroupInfo.setValue(value);
modifyGroupInfo.setNotify_message(notify_message);
return AdminHttpUtils.httpJsonPost(path, modifyGroupInfo, Void.class);
}
@@ -100,7 +101,17 @@ public class GroupAdmin {
return AdminHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
}
public static IMResult<Void> muteGroupMemeber(String operator, String groupId, List<String> groupMemberIds, boolean isManager, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
String path = APIPath.Group_Mute_Member;
InputMuteGroupMember addGroupMember = new InputMuteGroupMember();
addGroupMember.setGroup_id(groupId);
addGroupMember.setMembers(groupMemberIds);
addGroupMember.setIs_manager(isManager);
addGroupMember.setOperator(operator);
addGroupMember.setTo_lines(to_lines);
addGroupMember.setNotify_message(notify_message);
return AdminHttpUtils.httpJsonPost(path, addGroupMember, Void.class);
}
public static IMResult<Void> kickoffGroupMembers(String operator, String groupId, List<String> groupMemberIds, List<Integer> to_lines, MessagePayload notify_message) throws Exception {
String path = APIPath.Group_Member_Kickoff;
@@ -130,5 +141,4 @@ public class GroupAdmin {
return AdminHttpUtils.httpJsonPost(path, inputUserId, OutputGroupIds.class);
}
}
+175 -4
View File
@@ -6,6 +6,7 @@ import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.sdk.model.IMResult;
import cn.wildfirechat.sdk.utilities.AdminHttpUtils;
import cn.wildfirechat.sdk.utilities.RobotHttpUtils;
import io.netty.util.internal.StringUtil;
import java.util.ArrayList;
@@ -36,6 +37,7 @@ public class Main {
testChatroom();
testMessage();
testGeneralApi();
testDevice();
System.out.println("Congratulation, all admin test case passed!!!!!!!");
}
@@ -73,6 +75,8 @@ public class Main {
System.exit(-1);
}
IMResult<InputOutputUserInfo> resultGetUserInfo1 = UserAdmin.getUserByName(userInfo.getName());
if (resultGetUserInfo1 != null && resultGetUserInfo1.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
if (userInfo.getUserId().equals(resultGetUserInfo1.getResult().getUserId())
@@ -258,8 +262,8 @@ public class Main {
System.exit(-1);
}
updateFriendStatusResult = RelationAdmin.setUserBlacklist("ff1", "ff2", true);
if (updateFriendStatusResult != null && updateFriendStatusResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
IMResult<Void> updateBlacklistStatusResult = RelationAdmin.setUserBlacklist("ff1", "ff2", true);
if (updateBlacklistStatusResult != null && updateBlacklistStatusResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("update blacklist status success");
} else {
System.out.println("update blacklist status failure");
@@ -348,7 +352,7 @@ public class Main {
System.exit(-1);
}
voidIMResult = GroupAdmin.modifyGroupInfo(groupInfo.getOwner(), groupInfo.getTarget_id(), ProtoConstants.ModifyGroupInfoType.Modify_Group_Name,"HelloWorld", null);
voidIMResult = GroupAdmin.modifyGroupInfo(groupInfo.getOwner(), groupInfo.getTarget_id(), ProtoConstants.ModifyGroupInfoType.Modify_Group_Name,"HelloWorld", null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("transfer success");
} else {
@@ -410,6 +414,23 @@ public class Main {
System.exit(-1);
}
voidIMResult = GroupAdmin.muteGroupMemeber("user1", groupInfo.getTarget_id(), Arrays.asList("user4", "user5"), true, null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("mute group member success");
} else {
System.out.println("mute group member failure");
System.exit(-1);
}
voidIMResult = GroupAdmin.muteGroupMemeber("user1", groupInfo.getTarget_id(), Arrays.asList("user4", "user5"), false, null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("unmute group member success");
} else {
System.out.println("unmute group member failure");
System.exit(-1);
}
voidIMResult = GroupAdmin.quitGroup("user4", groupInfo.getTarget_id(), null, null);
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
@@ -462,6 +483,13 @@ public class Main {
System.exit(-1);
}
voidIMResult = MessageAdmin.deleteMessage(resultSendMessage.getResult().getMessageUid());
if (voidIMResult != null && voidIMResult.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("delete message success");
} else {
System.out.println("delete message failure");
System.exit(-1);
}
IMResult<BroadMessageResult> resultBroadcastMessage = MessageAdmin.broadcastMessage("user1", 0, payload);
if (resultBroadcastMessage != null && resultBroadcastMessage.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
@@ -546,7 +574,7 @@ public class Main {
System.out.println("chatroom info incorrect");
System.exit(-1);
} else {
System.out.println("chatroom info incorrect");
System.out.println("chatroom info correct");
}
} else {
System.out.println("get chatroom info failure");
@@ -575,6 +603,105 @@ public class Main {
System.out.println("chatroom not destroyed!");
System.exit(-1);
}
//下面仅专业版支持
/*
//设置用户聊天室黑名单。0正常;1禁言;2禁止加入。
IMResult<Void> voidIMResult1 = ChatroomAdmin.setChatroomBlacklist("chatroom1", "oto9o9__", 1);
if (voidIMResult1 != null && voidIMResult1.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("add chatroom black success");
} else {
System.out.println("add chatroom black failure");
System.exit(-1);
}
//获取聊天室黑名单
IMResult<OutputChatroomBlackInfos> blackInfos = ChatroomAdmin.getChatroomBlacklist("chatroom1");
if (blackInfos != null && blackInfos.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && !blackInfos.getResult().infos.isEmpty()) {
boolean success = false;
for (OutputChatroomBlackInfos.OutputChatroomBlackInfo info : blackInfos.getResult().infos) {
if (info.userId.equals("oto9o9__")) {
success = true;
break;
}
}
if (success) {
System.out.println("add chatroom black success");
} else {
System.out.println("add chatroom black failure");
System.exit(-1);
}
} else {
System.out.println("add chatroom black failure");
System.exit(-1);
}
//取消用户聊天室黑名单。0正常;1禁言;2禁止加入。
voidIMResult1 = ChatroomAdmin.setChatroomBlacklist("chatroom1", "oto9o9__", 0);
if (voidIMResult1 != null && voidIMResult1.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("remove chatroom black success");
} else {
System.out.println("remove chatroom black failure");
System.exit(-1);
}
//获取聊天室黑名单
blackInfos = ChatroomAdmin.getChatroomBlacklist("chatroom1");
if (blackInfos != null && blackInfos.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
boolean success = true;
for (OutputChatroomBlackInfos.OutputChatroomBlackInfo info : blackInfos.getResult().infos) {
if (info.userId.equals("oto9o9__")) {
success = false;
break;
}
}
if (success) {
System.out.println("remove chatroom black success");
} else {
System.out.println("remove chatroom black failure");
System.exit(-1);
}
} else {
System.out.println("remove chatroom black failure");
System.exit(-1);
}
//设置聊天室管理员
IMResult<Void> voidIMResult2 = ChatroomAdmin.setChatroomManager("chatroom1", "UserId1", 1);
if (voidIMResult2 != null && voidIMResult2.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("add chatroom manager success");
} else {
System.out.println("add chatroom black failure");
System.exit(-1);
}
//获取聊天室管理员
IMResult<OutputStringList> managers = ChatroomAdmin.getChatroomManagerList("chatroom1");
if (managers != null && managers.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && !managers.getResult().getList().isEmpty() && managers.getResult().getList().contains("UserId1")) {
System.out.println("add chatroom black success");
} else {
System.out.println("add chatroom black failure");
System.exit(-1);
}
//取消聊天室管理员
IMResult<Void> voidIMResult3 = ChatroomAdmin.setChatroomManager("chatroom1", "UserId1", 0);
if (voidIMResult3 != null && voidIMResult3.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("add chatroom manager success");
} else {
System.out.println("add chatroom black failure");
System.exit(-1);
}
//获取聊天室管理员
IMResult<OutputStringList> managers2 = ChatroomAdmin.getChatroomManagerList("chatroom1");
if (managers2 != null && managers2.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && !managers2.getResult().getList().contains("UserId1")) {
System.out.println("add chatroom black success");
} else {
System.out.println("add chatroom black failure");
System.exit(-1);
}*/
}
static void testRobot() throws Exception {
@@ -758,4 +885,48 @@ public class Main {
System.exit(-1);
}
}
//***********************************************
//**** 物联网相关的API,仅专业版支持
//***********************************************
static void testDevice() throws Exception {
InputCreateDevice createDevice = new InputCreateDevice();
createDevice.setDeviceId("deviceId1");
createDevice.setOwners(Arrays.asList("opoGoG__", "userId1"));
IMResult<OutputCreateDevice> resultCreateDevice = UserAdmin.createOrUpdateDevice(createDevice);
if (resultCreateDevice != null && resultCreateDevice.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
System.out.println("Create device " + resultCreateDevice.getResult().getDeviceId() + " success");
} else {
System.out.println("Create device failure");
System.exit(-1);
}
IMResult<OutputDevice> getDevice = UserAdmin.getDevice("deviceId1");
if (getDevice != null && getDevice.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && getDevice.getResult().getDeviceId().equals("deviceId1") && getDevice.getResult().getOwners().contains("opoGoG__")) {
System.out.println("Get device " + resultCreateDevice.getResult().getDeviceId() + " success");
} else {
System.out.println("Get device failure");
System.exit(-1);
}
IMResult<OutputDeviceList> getUserDevices = UserAdmin.getUserDevices("userId1");
if (getUserDevices != null && getUserDevices.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
boolean success = false;
for (OutputDevice outputDevice : getUserDevices.getResult().getDevices()) {
if (outputDevice.getDeviceId().equals("deviceId1")) {
success = true;
break;
}
}
if (success) {
System.out.println("Get user device success");
} else {
System.out.println("Get user device failure");
System.exit(-1);
}
} else {
System.out.println("Get device failure");
System.exit(-1);
}
}
}
@@ -25,6 +25,30 @@ public class MessageAdmin {
return AdminHttpUtils.httpJsonPost(path, messageData, Void.class);
}
public static IMResult<Void> deleteMessage(long messageUid) throws Exception {
String path = APIPath.Msg_Delete;
DeleteMessageData deleteMessageData = new DeleteMessageData();
deleteMessageData.setMessageUid(messageUid);
return AdminHttpUtils.httpJsonPost(path, deleteMessageData, Void.class);
}
/**
* 撤回群发或者广播的消息
* @param target 目标用户
* @param messageUid 消息唯一ID
* @return
* @throws Exception
*/
public static IMResult<Void> recallBroadcastOrMulticastMessage(String target, long messageUid) throws Exception {
String path = APIPath.Msg_Recall;
RecallMessageData messageData = new RecallMessageData();
messageData.setOperator(target);
messageData.setMessageUid(messageUid);
return AdminHttpUtils.httpJsonPost(path, messageData, Void.class);
}
public static IMResult<BroadMessageResult> broadcastMessage(String sender, int line, MessagePayload payload) throws Exception {
String path = APIPath.Msg_Broadcast;
BroadMessageData messageData = new BroadMessageData();
@@ -28,7 +28,7 @@ public class RelationAdmin {
InputBlacklistRequest input = new InputBlacklistRequest();
input.setUserId(userId);
input.setTargetUid(targetId);
input.setStatus(isBlacklist ? 1 : 0);
input.setStatus(isBlacklist ? 2 : 1);
return AdminHttpUtils.httpJsonPost(path, input, Void.class);
}
@@ -2,7 +2,6 @@ package cn.wildfirechat.sdk;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.pojos.*;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.sdk.model.IMResult;
import cn.wildfirechat.sdk.utilities.AdminHttpUtils;
@@ -71,14 +70,24 @@ public class UserAdmin {
return AdminHttpUtils.httpJsonPost(path, inputDestroyUser, Void.class);
}
//not implement
// public static IMResult<OutputUserBlockStatusList> getUserOnlineStatus(String userId) throws Exception {
// String path = APIPath.User_Get_Online_Status;
// InputGetUserInfo inputGetUserInfo = new InputGetUserInfo(userId, null);
// return AdminHttpUtils.httpJsonPost(path, null, OutputUserBlockStatusList.class);
// }
//仅专业版支持
public static IMResult<OutputCreateDevice> createOrUpdateDevice(InputCreateDevice device) throws Exception {
String path = APIPath.CreateOrUpdate_Device;
return AdminHttpUtils.httpJsonPost(path, device, OutputCreateDevice.class);
}
//仅专业版支持
public static IMResult<OutputDevice> getDevice(String deviceId) throws Exception {
String path = APIPath.Get_Device;
InputDeviceId inputDeviceId = new InputDeviceId();
inputDeviceId.setDeviceId(deviceId);
return AdminHttpUtils.httpJsonPost(path, inputDeviceId, OutputDevice.class);
}
public static IMResult<OutputDeviceList> getUserDevices(String userId) throws Exception {
String path = APIPath.Get_User_Devices;
InputUserId inputUserId = new InputUserId();
inputUserId.setUserId(userId);
return AdminHttpUtils.httpJsonPost(path, inputUserId, OutputDeviceList.class);
}
}
@@ -31,9 +31,13 @@ public class AdminHttpUtils {
}
public static <T> IMResult<T> httpJsonPost(String path, Object object, Class<T> clazz) throws Exception{
if (isNullOrEmpty(adminUrl) || isNullOrEmpty(path)) {
LOG.error("Not init IM SDK correctly. Do you forget init it?");
throw new Exception("SDK url or secret lack!");
if (isNullOrEmpty(adminUrl) || isNullOrEmpty(adminSecret)) {
LOG.error("野火IM Server SDK必须先初始化才能使用,是不是忘记初始化了!!!!");
throw new Exception("SDK没有初始化");
}
if (isNullOrEmpty(path)) {
throw new Exception("路径缺失");
}
String url = adminUrl + path;