Compare commits

..
105 Commits
Author SHA1 Message Date
heavyrian2012 ade58efc11 更新版本号和release note内容 2024-12-11 16:28:51 +08:00
heavyrian2012 d45da9674e 默认开启支持支持踢出事件的开关 2024-12-11 16:24:19 +08:00
heavyrian2012 f603a677ea 当禁止私聊时可以配置例外的线路 2024-12-06 16:06:04 +08:00
heavyrian2012 03894aea9a 修改启动成功的提示语 2024-12-06 08:02:30 +08:00
heavyrian2012 8635153e59 解决聊天室定向消息问题 2024-11-20 12:47:11 +08:00
heavyrian2012 3d98d17b0d 机器人接口添加更新朋友圈接口 2024-11-14 12:51:05 +08:00
heavyrian2012 0549bc502f 添加批量获取用户信息的接口 2024-11-14 12:50:38 +08:00
heavyrian2012 1b8cf3e5f9 添加机器人的朋友圈接口 2024-11-03 10:06:10 +08:00
heavyrian2012 f3f08b3026 version & release note 2024-10-30 19:12:31 +08:00
heavyrian2012 78e6efce14 透传消息需要带上时间戳 2024-10-30 19:00:35 +08:00
heavyrian2012 462423a6f3 SDK添加删除广播和组播接口 2024-10-28 22:08:20 +08:00
heavyrian2012 55190a4f76 优化生成测试数据工具 2024-10-26 14:13:56 +08:00
heavyrian2012 4ed21ecb03 添加生成测试工具的工具 2024-10-25 14:43:06 +08:00
heavyrian2012 1ff3b592bd 创建群组时检查操作者参数是不是存在 2024-10-25 14:42:55 +08:00
heavyrian2012 fbc2351d82 用户可以设置禁止添加好友 2024-10-02 20:07:17 +08:00
heavyrian2012 dd1783d4ac 透传消息去掉消息id和时间戳,减少消息体大小 2024-10-02 20:04:47 +08:00
heavyrian2012 845e6ff8aa version and release note 2024-09-29 08:18:17 +08:00
heavyrian2012 6d91f3869e 创建群组或者添加群组成员时,群组成员的Extra会放到通知消息的extra中,这样便于业务处理通知消息 2024-09-25 11:07:12 +08:00
heavyrian2012 d100bd5fb1 update readme 2024-09-18 20:19:15 +08:00
heavyrian2012 bf22b365a8 如果没有配置鸿蒙推送地址,不应该回落到Android,避免对android造成影响 2024-09-18 13:01:49 +08:00
heavyrian2012 f1298a51ae 添加鸿蒙推送回调地址 2024-09-18 12:50:19 +08:00
heavyrian2012 41f62c6354 添加配置,是否允许发送消息给黑名单用户 2024-09-14 09:53:50 +08:00
heavyrian2012 a45de0ecd1 添加好友请求限频功能 2024-09-12 21:34:12 +08:00
heavyrian2012 fc35865478 push message 添加 republish 属性 2024-09-12 21:29:03 +08:00
heavyrian2012 b1f59498e5 version and release note 2024-09-10 10:57:15 +08:00
heavyrian2012 04f5471385 用户id默认使用uuid 2024-09-10 10:53:21 +08:00
heavyrian2012 291fdfb08d 解决server api获取群组信息不全的问题 2024-09-03 14:58:00 +08:00
heavyrian2012 52de13e20d sdk中针对密钥错误给出提醒 2024-08-22 20:42:22 +08:00
heavyrian2012 c1d353bce9 version & release note 2024-08-19 09:28:38 +08:00
heavyrian2012 9d83f8e3fa 解决某些时候http请求返回信息无法读取问题 2024-08-14 08:35:39 +08:00
heavyrian2012 94833780ef update readme 2024-08-12 08:35:32 +08:00
heavyrian2012 d0fdf55db4 群组解散后撤回失败的错误码应该是不存在 2024-07-29 11:45:35 +08:00
heavyrian2012 ea00ef6b7f 添加发送消息的示例 2024-07-19 16:54:15 +08:00
heavyrian2012 a11cf3c564 解决群组标记删除错误 2024-07-19 16:24:36 +08:00
heavyrian2012 f5af956298 更新readme 2024-07-19 09:41:55 +08:00
heavyrian2012 4005a4babe 配置文件注释说明 2024-07-10 11:14:07 +08:00
heavyrian2012 6ef8b78452 server api获取被封禁用户时,过滤掉正常用户 2024-07-09 16:06:10 +08:00
heavyrian2012 100a1bd44c update readme 2024-07-07 11:02:38 +08:00
heavyrian2012 5a213704c5 version and release note 2024-06-30 12:17:37 +08:00
heavyrian2012 5a52a7d553 同步专业版IM服务 2024-06-30 12:13:21 +08:00
heavyrian2012 d751a7080b 添加Mesh相关SDK 2024-06-21 16:45:10 +08:00
heavyrian2012 68ae7dbd58 SDK中关于频道的api放到ChannelAdmin方法中 2024-06-11 09:10:17 +08:00
heavyrian2012 10fce4baad 解决机器人API修改机器人用户信息客户端没有更新的问题 2024-06-11 08:47:42 +08:00
heavyrian2012 c69906e249 添加频道新的回调特性 2024-05-29 16:30:54 +08:00
heavyrian2012 1aed4b1d37 搜索频道时,解决某些频道不能搜索出来的问题 2024-05-29 16:08:37 +08:00
heavyrian2012 f2601fc65d 针对非x86_64平台关于epoll的说明 2024-05-07 12:32:37 +08:00
heavyrian2012 4895f03a68 version and release note 2024-05-05 15:36:06 +08:00
heavyrian2012 1d234a3575 获取被删除群组时总是同步 2024-04-28 17:11:36 +08:00
heavyrian2012 386d0b9c57 删除无用代码 2024-04-27 08:35:55 +08:00
heavyrian2012 3ab1c7553d 如果用户不在群中,不再进行群组信息更新 2024-04-25 10:45:21 +08:00
heavyrian2012 85a4c806c1 退群时添加是否保留消息的参加 2024-04-25 10:44:50 +08:00
heavyrian2012 9aac87b7a1 拉取消息时,处理重复消息 2024-04-23 14:17:40 +08:00
heavyrian2012 ce21441772 群主强制被退群时(销毁账号/server api强制退群),调整新群主选择,群管理优先,先加入群组优先。 2024-04-23 13:28:53 +08:00
heavyrian2012 0a3516cdf2 version and release note 2024-04-19 11:28:17 +08:00
heavyrian2012 135a9ed0a8 添加用户设置添加好友验证功能 2024-04-19 11:19:43 +08:00
heavyrian2012 73e3447b39 强制推送配置默认为关闭 2024-04-03 10:51:06 +08:00
heavyrian2012 394b9119fa 添加配置,可以在会话静音/全局静音/PC在线时静音时强制推送。
(cherry picked from commit 1f4cf54990831d4bcc4fcec2fa5479036a581e58)
2024-04-03 10:49:47 +08:00
heavyrian2012 ebb05351a8 群组标记删除
(cherry picked from commit cdf4a0c011b879819c0263b84bddd2da5cb8bc7d)
2024-04-03 10:49:46 +08:00
heavyrian2012 c4421fc9ed server api添加通过邮箱获取用户列表的接口 2024-03-25 19:00:42 +08:00
heavyrian2012 a906bf352d version and release note 2024-03-25 09:04:28 +08:00
heavyrian2012 37f1772705 在线状态回调添加其他端的状态 2024-03-23 12:32:45 +08:00
heavyrian2012 0a05503c78 创建频道和机器人时,不再设置默认头像 2024-03-23 11:13:37 +08:00
heavyrian2012 a702602758 去掉用户信息中的密码处理 2024-03-23 11:13:09 +08:00
heavyrian2012 c01e5b634d version and release note 2024-03-07 16:33:50 +08:00
heavyrian2012 6c2848cbf7 升级依赖 2024-02-27 20:45:14 +08:00
heavyrian2012 ae3c8e0d25 升级部分依赖版本 2024-02-27 11:51:48 +08:00
heavyrian2012 2ef0059395 remove useless test code 2024-02-27 11:28:28 +08:00
heavyrian2012 d91a2d9fd5 升级部分依赖版本 2024-02-27 11:27:56 +08:00
heavyrian2012 a4bcd5e29e 同步专业版IM服务 2024-02-22 14:28:49 +08:00
heavyrian2012 fe4612c801 解决server端音视频SDK信令透传问题 2024-02-22 14:26:04 +08:00
heavyrian2012 58ade23b23 添加鸿蒙平台的支持 2024-02-04 17:02:20 +08:00
heavyrian2012 f1e46fca75 同步专业版IM服务 2024-02-02 13:44:47 +08:00
heavyrian2012 1e17fa1db4 同步专业版IM SDK 2024-02-02 12:50:23 +08:00
heavyrian2012 7094114ea3 同步专业版IM服务SDK 2024-01-27 14:13:14 +08:00
heavyrian2012 c805bddca1 version and release note 2024-01-14 10:47:49 +08:00
heavyrian2012 cb5754fe07 群组信息变更回调中加上群组信息 2024-01-14 09:51:46 +08:00
heavyrian2012 c014b78d95 1,添加配置,可以禁止拉陌生人进群
2,拉人进群时检查是否被拉黑
2024-01-14 09:42:42 +08:00
heavyrian2012 8a13a32615 sdk支持流式文本 2023-12-30 19:09:30 +08:00
heavyrian2012 bc409042b0 解决搜索时特殊字符的转义问题 2023-12-27 20:07:48 +08:00
heavyrian2012 49ad4f5eb6 机器人sdk添加撤回和更新接口 2023-12-26 09:20:34 +08:00
heavyrian2012 8c93e2ee42 update readme 2023-12-11 10:55:30 +08:00
heavyrian2012 54286b4a55 release note and version 2023-12-03 11:43:41 +08:00
heavyrian2012 594103e06b 解决广播没有发送消息给未登录用户的问题 2023-12-02 23:03:00 +08:00
heavyrian2012 90e89978aa 消息表的消息id索引改成唯一索引,只对新库有效,已有数据库不影响。 2023-12-02 17:01:03 +08:00
heavyrian2012 93b6e70804 优化用户id搜索逻辑 2023-11-30 19:44:06 +08:00
heavyrian2012 b774e0d423 添加获取在线用户信息和获取用户session信息的接口 2023-11-28 11:04:12 +08:00
heavyrian2012 08b813cd9f version 1.2.0 and release note 2023-11-18 20:28:35 +08:00
heavyrian2012 24c6538084 添加配置,处理多端同时加入聊天室的问题 2023-11-17 09:06:49 +08:00
heavyrian2012 724be0b273 添加获取用户聊天室状态的API 2023-11-17 09:06:00 +08:00
heavyrian2012 63f0fc66ce 支持按照用户ID来搜索用户 2023-11-15 15:38:22 +08:00
heavyrian2012 327b8d43a8 解决某些特殊情况下获取网卡信息失败导致启动失败的问题 2023-11-15 10:21:57 +08:00
imndx df67b8e0c8 禁止私聊时,只要发送者或接受者一方在允许私聊的列表里面,就允许私聊 fix #663 2023-11-10 11:00:45 +08:00
heavyrian2012 b4fcef1ced 会议事件添加时间戳 2023-11-05 10:51:46 +08:00
heavyrian2012 c43dfe26f4 更新SDK的依赖说明 2023-10-21 10:22:24 +08:00
heavyrian2012 aa1161131d 更新readme 2023-10-14 09:11:25 +08:00
heavyrian2012 a1188f5d52 添加配置开关,可以关掉api/version检查接口 2023-10-12 15:44:00 +08:00
heavyrian2012 6a10412940 version 1.1.9 and release note 2023-10-12 10:17:12 +08:00
heavyrian2012 8e3100e5b7 添加配置,是否允许群主和群管理员不受限制撤回自己的发言 2023-10-10 21:53:03 +08:00
heavyrian2012 c17a5be171 支持获取用户群组指定群成员类型 2023-10-10 12:51:40 +08:00
heavyrian2012 7727fad4dc 避免无限制重复好友请求,好友请求在5分钟之内只允许重复请求一次 2023-09-29 11:26:16 +08:00
heavyrian2012 dd5b9b1847 解决好友请求被拒绝后可能还能再次请求的问题 2023-09-29 10:45:41 +08:00
heavyrian2012 92c3c98553 解决重复发送好友请求时,请求时间没有更新的问题 2023-09-29 10:32:52 +08:00
heavyrian2012 d13ed6f989 sdk打印出请求的完整路径,方便问题排查 2023-09-26 09:58:12 +08:00
heavyrian2012 4e6188ee32 添加推送过期配置 2023-09-13 11:16:54 +08:00
heavyrian2012 a183d30f89 解决服务器时间过大的问题 https://github.com/wildfirechat/android-chat/issues/795 2023-09-11 11:12:50 +08:00
184 changed files with 7241 additions and 807 deletions
+36 -4
View File
@@ -7,9 +7,9 @@
* 性能强大,专业版IM服务支持百万在线和集群部署,业内顶尖性能水平,详情参考野火性能报告。 * 性能强大,专业版IM服务支持百万在线和集群部署,业内顶尖性能水平,详情参考野火性能报告。
* 部署运维简单,依赖服务少,稍加配置一键启动。 * 部署运维简单,依赖服务少,稍加配置一键启动。
* 安全加密。网络连接AES加密。客户端数据库SqlCipher加密。安全无小事。 * 安全加密。网络连接AES加密。客户端数据库SqlCipher加密。安全无小事。
* 全平台客户端,支持Android、iOS、Web、小程序、UniApp、Flutter、Windows、Mac OS、Linux等所有常见平台。 * 全平台客户端,支持Android、iOS、鸿蒙、Web、小程序、UniApp、Flutter、Windows、Mac OS、Linux等所有常见平台。
* 四端同时在线(移动端,pc端,web端和小程序端),数据和状态多端完美同步。 * 四端同时在线(移动端,pc端,web端和小程序端),数据和状态多端完美同步。
* 支持国产化。支持国产化操作系统、国产化芯片和国产操作系统。支持国密加密。 * 支持国产化。支持国产化操作系统、国产化芯片和国产数据库。支持国密加密。
* 客户端使用微信[mars](https://github.com/tencent/mars)连接库,野火IM可能是最适应中国网络国情的即时通讯服务。 * 客户端使用微信[mars](https://github.com/tencent/mars)连接库,野火IM可能是最适应中国网络国情的即时通讯服务。
* 支持加速点加速,即可用于全球应用,也可用于政企内外双网复杂的网络环境。 * 支持加速点加速,即可用于全球应用,也可用于政企内外双网复杂的网络环境。
* 支持阅读回执和在线状态功能,适用于办公环境。 * 支持阅读回执和在线状态功能,适用于办公环境。
@@ -22,9 +22,10 @@
* API丰富,方便与其它服务系统的对接。 * API丰富,方便与其它服务系统的对接。
* 拥有机器人和公众号功能,免费的频道(公众号)管理后台。 * 拥有机器人和公众号功能,免费的频道(公众号)管理后台。
* 超级群组功能,可以支持万人大群。 * 超级群组功能,可以支持万人大群。
* 支持多个IM服务组网互通,打破孤岛,适用于集团公司下多个分公司互联互通。
* 社区版IM服务和移动端免费商用,可以免费构建出完备的移动互联网应用。 * 社区版IM服务和移动端免费商用,可以免费构建出完备的移动互联网应用。
* 收费项目非常便宜,野火独有的试用模式,可以先部署到客户环境试用6个月,试用满意后再购买,避免上当受骗。 * 收费项目非常便宜,野火独有的试用模式,可以先部署到客户环境试用6个月,试用满意后再购买,避免上当受骗。
* 技术支持专业和高效,核心研发人员及时处理issue和论坛回复。 * 技术支持专业高效,***核心研发***及时处理issue和工单,能最快解决用户的技术难题。技术支持不收费,让客户顺利使用是我们最大的愿望。
## 野火开源项目 ## 野火开源项目
主要包括以下项目: 主要包括以下项目:
@@ -54,6 +55,9 @@
## 野火开发文档 ## 野火开发文档
[在线文档](https://docs.wildfirechat.cn/) [在线文档](https://docs.wildfirechat.cn/)
## 野火IM论坛
[野火IM论坛](https://bbs.wildfirechat.cn)
## 野火性能测试报告及测试方法 ## 野火性能测试报告及测试方法
[Github](https://github.com/wildfirechat/Performance_Test), [码云](https://gitee.com/wfchat/Performance_Test)。 [Github](https://github.com/wildfirechat/Performance_Test), [码云](https://gitee.com/wfchat/Performance_Test)。
@@ -70,7 +74,7 @@ PC客户端点[这里](https://github.com/wildfirechat/vue-pc-chat/releases)下
![野火IM](http://static.wildfirechat.net/wx.jpg) ![野火IM](http://static.wildfirechat.net/wx.jpg)
## 快速使用 ## 快速开始
可以按照[快速开始](https://docs.wildfirechat.cn/quick_start/)来部署应用服务和IM服务,然后打包移动端,就可以完成聊天和通话功能。 可以按照[快速开始](https://docs.wildfirechat.cn/quick_start/)来部署应用服务和IM服务,然后打包移动端,就可以完成聊天和通话功能。
之后再部署开放平台服务、频道(公众号)服务、机器人服务、推送服务、Turn服务(音视频服务)来实现完整的应用功能,详情可以详细阅读文档。 之后再部署开放平台服务、频道(公众号)服务、机器人服务、推送服务、Turn服务(音视频服务)来实现完整的应用功能,详情可以详细阅读文档。
@@ -116,6 +120,19 @@ mvn clean package
修改之后运行编译命令```mvn clean package```,rpm包生成在```distribution/target```目录下。 修改之后运行编译命令```mvn clean package```,rpm包生成在```distribution/target```目录下。
## Epoll
在linux系统中打开Epoll开关可以提高性能,默认软件包内打包的是x86_64的epoll native sdk。如果是arm64的机器,可以把[broker pom](./broker/pom.xml)文件中修改如下:
```xml
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<version>${netty.version}</version>
<!-- <classifier>linux-x86_64</classifier>-->
<classifier>linux-aarch_64</classifier>
</dependency>
```
然后重新打包。专业版IM服务软件包中有arm64架构的sdk,可以直接替换。epoll只支持x86_64和arm64两个架构,其他架构不要把epoll开关打开。
## 升级说明 ## 升级说明
1. 从0.42 版本增加了群成员数限制,默认为2000。如果您从之前的版本升级到这个版本或以后,需要注意到群成员数的限制。升级之后超出限制的群不受影响,但不能继续加人,如果您想修改默认值,可以在升级版本之后,修改t_setting表,把默认的大小改为您期望的人数。另外修改t_group表,把已经存在的群组max_member_count改成您期望的,然后重启。 1. 从0.42 版本增加了群成员数限制,默认为2000。如果您从之前的版本升级到这个版本或以后,需要注意到群成员数的限制。升级之后超出限制的群不受影响,但不能继续加人,如果您想修改默认值,可以在升级版本之后,修改t_setting表,把默认的大小改为您期望的人数。另外修改t_group表,把已经存在的群组max_member_count改成您期望的,然后重启。
2. 0.50版本添加了是否允许客户端发送群操作通知的配置。如果您在客户端自定义群通知,需要在服务器端配置允许,没有使用自定义群操作通知的不受影响。*** 2. 0.50版本添加了是否允许客户端发送群操作通知的配置。如果您在客户端自定义群通知,需要在服务器端配置允许,没有使用自定义群操作通知的不受影响。***
@@ -128,6 +145,21 @@ mvn clean package
9. 从0.79 版本起把log4j升级到log4j2,因为log4j已经不再维护而且还有已知的漏洞,建议所有客户都升级,升级时注意更新log4j2的配置文件 9. 从0.79 版本起把log4j升级到log4j2,因为log4j已经不再维护而且还有已知的漏洞,建议所有客户都升级,升级时注意更新log4j2的配置文件
10. 0.97版本更改了启动脚本```wildfirechat.sh```,如果是升级服务,请注意更新启动脚本。 10. 0.97版本更改了启动脚本```wildfirechat.sh```,如果是升级服务,请注意更新启动脚本。
## 维护说明
野火设计理念当中,IM服务和客户端协议栈构成个管道工具,数据在人和人或者人和服务或者服务和服务之间传递,可以通过Server API和自定义消息来对接和开发业务。业务系统把IM系统当作一个工具来使用,是不需要把任何业务逻辑写在IM服务中的。
如果修改了IM服务可能会引起跟客户端协议栈的不兼容,以后也没有可能从社区版IM服务迁移到专业版IM服务,还有一旦修改就跟我们代码不一样了,如果出了问题我们就无法分析和解决。所以 ***我们强烈不推荐在IM服务修改代码,如果修改过就不再提供任何技术支持和服务了***。除了IM服务以外的所有代码可以任意修改。
现有接口足够对接和二开任何业务了,如果发现无法实现你们的业务需求,可以在[论坛](https://bbs.wildfirechat.cn)来咨询,我们会分析如何实现,如果需要添加新接口,我们会及时免费添加。请切记:***不要修改IM服务的代码!*** ***不要修改IM服务的代码!*** ***不要修改IM服务的代码!***
详细维护说明请参考 [野火维护说明](https://docs.wildfirechat.cn/base_knowledge/maintain.html)。
## 服务对象
因为野火的使用范围比较广,难免被一些不法分子利用,国内反诈反赌力度很大,所以国内多地警方都跟我们都有过联系。***为了预防我们的产品被用于非法目的,试用及购买只能支持境内法人单位,不接受个人或者境外团体。如果我们发现产品被用于非法目的,我们会立即停止技术支持服务并且报警和配合警方调查。请用于非法目的用户绕行!***
## 常见问题
请参考文档[常见问题](https://docs.wildfirechat.cn/faq/server.html)
## 应用截图 ## 应用截图
登录界面 登录界面
+73 -12
View File
@@ -68,6 +68,10 @@ token.key testim
##是否使用AES256加密。默认客户端和服务器都是AES128加密,如果需要开启AES256,需要客户端和IM服务同时开通。 ##是否使用AES256加密。默认客户端和服务器都是AES128加密,如果需要开启AES256,需要客户端和IM服务同时开通。
#encrypt.use_aes256 true #encrypt.use_aes256 true
##当创建一个对象时(用户,群组,频道,机器人等),如果没有传入ID,野火会为这个对象生成一个ID。如果id.use_uuid为true,会使用uuid作为对象ID,否则会使用野火短ID,默认为false。
## 短ID有个很大的风险是容易被人穷举进行攻击。建议用UUID。
id.use_uuid true
##首次登录,是否接收之前的历史消息。 ##首次登录,是否接收之前的历史消息。
##0 不接收历史消息,只接收${message.compensate_time_limit}毫秒以内的消息,由于服务器没有保存已经收取记录,所以如果有超过${message.compensate_time_limit}毫秒之前未收取的消息也不会收取下拉; ##0 不接收历史消息,只接收${message.compensate_time_limit}毫秒以内的消息,由于服务器没有保存已经收取记录,所以如果有超过${message.compensate_time_limit}毫秒之前未收取的消息也不会收取下拉;
##1接收,会接收 message.max_queue 配置的条数的历史消息 ##1接收,会接收 message.max_queue 配置的条数的历史消息
@@ -91,9 +95,15 @@ message.disable_stranger_chat false
##当禁止陌生人聊天时,允许聊天的用户id,比如管理员或者文件传输助手等。用户id以英文逗号分割。 ##当禁止陌生人聊天时,允许聊天的用户id,比如管理员或者文件传输助手等。用户id以英文逗号分割。
message.allow_stranger_chat_list admin,FireRobot,wfc_file_transfer message.allow_stranger_chat_list admin,FireRobot,wfc_file_transfer
##当禁止陌生人聊天时,允许聊天的线路。
#message.allow_stranger_line 100,101
##黑名单策略,0 发送失败,返回被拉黑的错误码;1 发送成功但消息被服务器直接丢弃 ##黑名单策略,0 发送失败,返回被拉黑的错误码;1 发送成功但消息被服务器直接丢弃
message.blacklist.strategy 0 message.blacklist.strategy 0
##拉黑对方后,对方不能发送消息给你。这个开关确定拉黑对方后你还能不能给对方发送消息。
message.blacklist.allow_send_to_black false
##是否禁止服务器端消息搜索,该功能暂未实现。目前的影响是如果打开,则存储消息时不单独保存_searchable_content字段 ##是否禁止服务器端消息搜索,该功能暂未实现。目前的影响是如果打开,则存储消息时不单独保存_searchable_content字段
message.disable_remote_search false message.disable_remote_search false
@@ -123,6 +133,18 @@ message.group_mute_exception_types 401,402,403,404,405,407,408,410,411
## 用户被全局禁言时允许发送的消息类型 ## 用户被全局禁言时允许发送的消息类型
message.global_mute_exception_types 401,402,403,404,405,407,408,410,411 message.global_mute_exception_types 401,402,403,404,405,407,408,410,411
## 离线用户推送过期天数,0是永不过期,建议配置为7天。
message.push_expired_days 7
## 当会话静音/全局静音/PC在线静音时,普通消息都不会有推送,如果有某些消息类型需要此时保持推送,可以配置到这里。此配置对消息免打扰时段无效。
## 此配置只影响远程推送,需要客户端处理客户端在线且在后台收到此消息的处理,需要针对这些消息类型加上本地通知。
## 强制推送消息的MessagePayload中pushContent和pushData至少要存在一个才可以推送。
## 消息类型以英文逗号分割。
#message.force_push_types 401,402
## 群发消息(包括server api群发和全局频道群发)时,目标用户是否来自于t_user表。如果使用野火托管用户信息,请设置为true,否则设置为false。
message.broadcast.target_from_user_table true
## 消息转发功能开启时,开关是否不转发server api接口消息。 ## 消息转发功能开启时,开关是否不转发server api接口消息。
## 当为true时,不转发server api发送的消息;当为false时,转发server api发送的消息。 ## 当为true时,不转发server api发送的消息;当为false时,转发server api发送的消息。
message.no_forward_admin_message false message.no_forward_admin_message false
@@ -136,12 +158,19 @@ robot.callback_with_client_info false
## 频道回调信息是否带上用户clientId和平台类型。 ## 频道回调信息是否带上用户clientId和平台类型。
channel.callback_with_client_info false channel.callback_with_client_info false
## 频道回调新方式,在新方式下,如果有callback地址就会总是回调客户端发送的消息(包括owner和订阅者)。automatic属性控制订阅者发送的消息是否发给owner, 0发,1不发。
## 旧的方式是,automatic为0时,订阅者的消息发给owner,不转发消息到callback地址。为1时,把订阅者的消息转发给callback地址,不发给owner。
channel.new_callback_feature true
##禁止搜索用户 ##禁止搜索用户
friend.disable_search false friend.disable_search false
##禁止按照昵称搜索用户。 ##禁止按照昵称搜索用户。
friend.disable_nick_name_search false friend.disable_nick_name_search false
##禁止按照用户id搜索用户,默认为true。
friend.disable_user_id_search true
##禁止发送好友邀请,通过server api添加好友不受此限制(force参数需要为true) ##禁止发送好友邀请,通过server api添加好友不受此限制(force参数需要为true)
friend.disable_friend_request false friend.disable_friend_request false
@@ -154,6 +183,9 @@ friend.reject_request_duration 2592000000
##好友请求过期时间,单位是毫秒,默认是7天,0为无限长期限。 ##好友请求过期时间,单位是毫秒,默认是7天,0为无限长期限。
friend.request_expiration_duration 604800000 friend.request_expiration_duration 604800000
##好友请求限制频率,一个用户24小时之内允许请求好友的次数,默认不限频。
friend.request_rate_limit 30
##请求添加机器人为好友时,机器人是否自动接受,默认为true ##请求添加机器人为好友时,机器人是否自动接受,默认为true
friend.robot_auto_accept true friend.robot_auto_accept true
@@ -166,6 +198,18 @@ chatroom.rejoin_when_active true
## 当一个聊天室不存在时,如果有用户加入就自动创建 ## 当一个聊天室不存在时,如果有用户加入就自动创建
chatroom.create_when_not_exist true chatroom.create_when_not_exist true
## 一个用户同一时刻只能加入一个聊天室。
## 当一个客户端加入一个聊天室时,如果这个客户端已经加入另外一个聊天室了,会自动退出之前的聊天室。
## 当一个客户端加入一个聊天室时,如果这个用户的其他端已经加入一个聊天室了,kickoff_other_platform为true时会自动退出之前的聊天室,为false时会返回225的错误码。
## 当自动退出聊天室时,客户端不会收到任何通知,只是不会再收到消息。
chatroom.kickoff_other_platform true
## 是否允许群主不受限制地撤回自己发送的消息。false可以${message.recall_time_limit}撤回自己的消息;true可以撤回任意时间自己的消息。默认为true。
group.allow_owner_recall_self_msg true
## 是否允许群管理员不受限制地撤回自己发送的消息。false可以${message.recall_time_limit}撤回自己的消息;true可以撤回任意时间自己的消息。默认为false。
group.allow_manager_recall_self_msg false
## 是否允许客户端发送操作群的自定义群通知消息 ## 是否允许客户端发送操作群的自定义群通知消息
group.allow_client_custom_operation_notification true group.allow_client_custom_operation_notification true
@@ -180,6 +224,12 @@ group.visible_quit_or_kickoff_notification 0
## Server API不受此限制。 ## Server API不受此限制。
#group.forbidden_client_operation 0xFFF #group.forbidden_client_operation 0xFFF
## 是否禁止陌生人拉人入群,默认为false
group.disable_stranger_invite false
## 群组信息是否标记删除
group.enable_mark_deletion true
## 隐藏用户信息属性类型,2是性别,3是电话号码,4是邮箱,5是地址,6是公司信息,7是社交账号,8是Extra信息。当需要隐藏多个时以英文逗号分开; ## 隐藏用户信息属性类型,2是性别,3是电话号码,4是邮箱,5是地址,6是公司信息,7是社交账号,8是Extra信息。当需要隐藏多个时以英文逗号分开;
## 本配置是为了提高安全性,避免把对应信息同步到客户端,这样就能防止程序被破解从而拿到用户关键信息。仅对客户端有效,server api不受影响。 ## 本配置是为了提高安全性,避免把对应信息同步到客户端,这样就能防止程序被破解从而拿到用户关键信息。仅对客户端有效,server api不受影响。
## 注意,修改本配置不会对已经同步的信息产生影响。 ## 注意,修改本配置不会对已经同步的信息产生影响。
@@ -192,6 +242,9 @@ user.keep_display_name_when_destroy true
# 因此需要分段多次同步,此开关定义了每次同步的数据的条数。此需要客户端支持,客户端SDK在2021.5.25日后支持此功能。如果确认所有客户端都在这个日志之后才可以打开此设置。 # 因此需要分段多次同步,此开关定义了每次同步的数据的条数。此需要客户端支持,客户端SDK在2021.5.25日后支持此功能。如果确认所有客户端都在这个日志之后才可以打开此设置。
#sync.data_part_size 1000 #sync.data_part_size 1000
## 是否关闭api/version接口。api/version方法可以用来检查IM服务版本,上线确认无问题后,可以关掉这个接口。
#http.close_api_version false
#********************************************************************* #*********************************************************************
# 限频配置 # 限频配置
#********************************************************************* #*********************************************************************
@@ -214,15 +267,6 @@ client.request_rate_limit 100
##关于对象存储的详细信息请参考:https://docs.wildfirechat.cn/server/oss.html ##关于对象存储的详细信息请参考:https://docs.wildfirechat.cn/server/oss.html
media.server.use_qiniu 0 media.server.use_qiniu 0
##媒体类型分类
#Media_Type_GENERAL = 0,
#Media_Type_IMAGE = 1,
#Media_Type_VOICE = 2,
#Media_Type_VIDEO = 3,
#Media_Type_FILE = 4,
#Media_Type_PORTRAIT = 5,
#Media_Type_FAVORITE = 6
# qiniu media server configuration # qiniu media server configuration
qiniu.server_url http://up.qbox.me qiniu.server_url http://up.qbox.me
qiniu.access_key tU3vdBK5BL5j4N7jI5N5uZgq_HQDo170w5C9Amnn qiniu.access_key tU3vdBK5BL5j4N7jI5N5uZgq_HQDo170w5C9Amnn
@@ -246,11 +290,21 @@ qiniu.bucket_portrait_domain http://cdn2.wildfirechat.cn
qiniu.bucket_favorite_name storage qiniu.bucket_favorite_name storage
qiniu.bucket_favorite_domain http://cdn2.wildfirechat.cn qiniu.bucket_favorite_domain http://cdn2.wildfirechat.cn
##媒体类型分类
#Media_Type_GENERAL = 0,
#Media_Type_IMAGE = 1,
#Media_Type_VOICE = 2,
#Media_Type_VIDEO = 3,
#Media_Type_FILE = 4,
#Media_Type_PORTRAIT = 5,
#Media_Type_FAVORITE = 6,
#Media_Type_STICKER = 7,
#Media_Type_MOMENTS = 8
# local media server configuration # local media server configuration
# 本地媒体服务器配置。 # 本地媒体服务器配置。
local.media.storage.root media local.media.storage.root media
# 如果使用内置文件存储,文件上传后地址默认为 http://server.ip:http_port/fs/5/2021/03/27/08/filename。 # 如果使用内置文件存储,文件上传后地址默认为 http://server.ip:http_port/fs/5/2021/03/27/08/filename。fs目录下按照类型存放文件,媒体类型见上面注释,比如5就是Media_Type_PORTRAIT,是客户端的头像文件。
# 如果需要使用nginx添加https支持,请打开下面配置,这样客户端得到的文件地址为 https://example.com/media/fs/5/2021/03/27/08/filename。 # 如果需要使用nginx添加https支持,请打开下面配置,这样客户端得到的文件地址为 https://example.com/media/fs/5/2021/03/27/08/filename。
# 需要nginx把请求从https://example.com/media/fs 转到 http://server.ip:http_port/fs。注意需要带上所有header。 # 需要nginx把请求从https://example.com/media/fs 转到 http://server.ip:http_port/fs。注意需要带上所有header。
# 尽管内置文件存储可以使用,但是我们还是建议使用专业级别的对象存储服务,社区版可以使用七牛,专业版另外支持阿里云和也是私有对象存储。详情请参考 https://docs.wildfirechat.cn/server/oss.html # 尽管内置文件存储可以使用,但是我们还是建议使用专业级别的对象存储服务,社区版可以使用七牛,专业版另外支持阿里云和也是私有对象存储。详情请参考 https://docs.wildfirechat.cn/server/oss.html
@@ -264,7 +318,10 @@ server.multi_endpoint false
## 是否支持PC多端登陆,当server.multi_endpoint为true时,此开关无意义,当为false时,可以单独打开PC端多端登录。 ## 是否支持PC多端登陆,当server.multi_endpoint为true时,此开关无意义,当为false时,可以单独打开PC端多端登录。
server.multi_pc_endpoint false server.multi_pc_endpoint false
# 多平台连接状态通知(仅当multi_endpoint为false时有效),true时移动端可以收到pc或web端登录的通知。 ## 是否支持PAD多端登陆,当server.multi_endpoint为true时,此开关无意义,当为false时,可以单独打开PAD端多端登录。
server.multi_pad_endpoint false
# 多平台连接状态通知(仅当multi_endpoint为false时有效),true时移动端可以收到pc或pad或web端登录的通知。
server.multi_platform_notification true server.multi_platform_notification true
# 当pc或者web在线时,手机是否默认静音,默认为true。注意仅影响默认值,用户可以手动切换是否静音。 # 当pc或者web在线时,手机是否默认静音,默认为true。注意仅影响默认值,用户可以手动切换是否静音。
@@ -273,7 +330,7 @@ server.mobile_default_silent_when_pc_online true
## 客户端是否支持kickoff事件。当客户端被其他端登录踢出时,如果此开关为false时,客户端协议栈上报secret_mismatch。如果此开关为ture时,客户端协议栈上报kicked_off。 ## 客户端是否支持kickoff事件。当客户端被其他端登录踢出时,如果此开关为false时,客户端协议栈上报secret_mismatch。如果此开关为ture时,客户端协议栈上报kicked_off。
## 客户端被踢时上报kicked_off是在2021.9.15之后才加上的。如果客户端协议栈全部为此日期之后的版本才可以打开此开关。 ## 客户端被踢时上报kicked_off是在2021.9.15之后才加上的。如果客户端协议栈全部为此日期之后的版本才可以打开此开关。
server.client_support_kickoff_event false server.client_support_kickoff_event true
#********************************************************************* #*********************************************************************
# Push server configuration # Push server configuration
@@ -287,6 +344,10 @@ push.android.server.address http://localhost:8085/android/push
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!! ##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
push.ios.server.address http://localhost:8085/ios/push push.ios.server.address http://localhost:8085/ios/push
##鸿蒙推送服务器地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
push.harmony.server.address http://localhost:8085/harmony/push
#********************************************************************* #*********************************************************************
# 监控配置 # 监控配置
#********************************************************************* #*********************************************************************
+2
View File
@@ -0,0 +1,2 @@
alter table `t_group` add column `_deleted` tinyint NOT NULL DEFAULT 0;
+13
View File
@@ -0,0 +1,13 @@
DROP TABLE IF EXISTS `t_domain`;
CREATE TABLE `t_domain` (
`_domain_id` varchar(64) NOT NULL PRIMARY KEY,
`_name` varchar(64) NOT NULL,
`_desc` varchar(256) DEFAULT '',
`_email` varchar(64) DEFAULT '',
`_tel` varchar(64) DEFAULT '',
`_address` varchar(64) DEFAULT '',
`_extra` varchar(1024) DEFAULT '',
`_dt` bigint(20) NOT NULL
);
alter table `t_user` add column `_external` tinyint DEFAULT 0;
@@ -10,7 +10,7 @@ CREATE TABLE `t_messages_0` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -28,7 +28,7 @@ CREATE TABLE `t_messages_1` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -46,7 +46,7 @@ CREATE TABLE `t_messages_2` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -63,7 +63,7 @@ CREATE TABLE `t_messages_3` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -81,7 +81,7 @@ CREATE TABLE `t_messages_4` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -99,7 +99,7 @@ CREATE TABLE `t_messages_5` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -116,7 +116,7 @@ CREATE TABLE `t_messages_6` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -134,7 +134,7 @@ CREATE TABLE `t_messages_7` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -152,7 +152,7 @@ CREATE TABLE `t_messages_8` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -169,7 +169,7 @@ CREATE TABLE `t_messages_9` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -187,7 +187,7 @@ CREATE TABLE `t_messages_10` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -205,7 +205,7 @@ CREATE TABLE `t_messages_11` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -222,7 +222,7 @@ CREATE TABLE `t_messages_12` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -240,7 +240,7 @@ CREATE TABLE `t_messages_13` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -258,7 +258,7 @@ CREATE TABLE `t_messages_14` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -275,7 +275,7 @@ CREATE TABLE `t_messages_15` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -293,7 +293,7 @@ CREATE TABLE `t_messages_16` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -311,7 +311,7 @@ CREATE TABLE `t_messages_17` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -328,7 +328,7 @@ CREATE TABLE `t_messages_18` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -346,7 +346,7 @@ CREATE TABLE `t_messages_19` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -364,7 +364,7 @@ CREATE TABLE `t_messages_20` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -381,7 +381,7 @@ CREATE TABLE `t_messages_21` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -399,7 +399,7 @@ CREATE TABLE `t_messages_22` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -417,7 +417,7 @@ CREATE TABLE `t_messages_23` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -434,7 +434,7 @@ CREATE TABLE `t_messages_24` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -452,7 +452,7 @@ CREATE TABLE `t_messages_25` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -470,7 +470,7 @@ CREATE TABLE `t_messages_26` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -487,7 +487,7 @@ CREATE TABLE `t_messages_27` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -505,7 +505,7 @@ CREATE TABLE `t_messages_28` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -523,7 +523,7 @@ CREATE TABLE `t_messages_29` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -540,7 +540,7 @@ CREATE TABLE `t_messages_30` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -558,7 +558,7 @@ CREATE TABLE `t_messages_31` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -576,7 +576,7 @@ CREATE TABLE `t_messages_32` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -593,7 +593,7 @@ CREATE TABLE `t_messages_33` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -611,7 +611,7 @@ CREATE TABLE `t_messages_34` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
@@ -629,7 +629,7 @@ CREATE TABLE `t_messages_35` (
`_data` BLOB NOT NULL, `_data` BLOB NOT NULL,
`_searchable_key` TEXT DEFAULT NULL, `_searchable_key` TEXT DEFAULT NULL,
`_dt` DATETIME NOT NULL, `_dt` DATETIME NOT NULL,
INDEX `message_uid_index` (`_mid` DESC) UNIQUE INDEX `message_uid_index` (`_mid` DESC)
) )
ENGINE = InnoDB ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4 DEFAULT CHARACTER SET = utf8mb4
+1
View File
@@ -0,0 +1 @@
alter table `t_group` add column `_deleted` tinyint NOT NULL DEFAULT 0;
+16
View File
@@ -0,0 +1,16 @@
DROP TABLE IF EXISTS `t_domain`;
CREATE TABLE `t_domain` (
`_domain_id` varchar(128) NOT NULL PRIMARY KEY,
`_name` varchar(64) NOT NULL,
`_desc` varchar(256) DEFAULT '',
`_email` varchar(64) DEFAULT '',
`_tel` varchar(64) DEFAULT '',
`_address` varchar(64) DEFAULT '',
`_extra` varchar(1024) DEFAULT '',
`_dt` bigint(20) NOT NULL
)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
alter table `t_user` add column `_external` tinyint DEFAULT 0;
+22 -55
View File
@@ -5,7 +5,7 @@
<relativePath>../</relativePath> <relativePath>../</relativePath>
<artifactId>wildfirechat-parent</artifactId> <artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId> <groupId>cn.wildfirechat</groupId>
<version>1.1.8</version> <version>1.3.2</version>
</parent> </parent>
<artifactId>moquette-broker</artifactId> <artifactId>moquette-broker</artifactId>
@@ -37,14 +37,14 @@
<!--用于与slf4j保持桥接--> <!--用于与slf4j保持桥接-->
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId> <artifactId>log4j-slf4j2-impl</artifactId>
<version>2.17.2</version> <version>2.22.1</version>
</dependency> </dependency>
<!-- slf4j核心包--> <!-- slf4j核心包-->
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
<version>1.7.25</version> <version>2.0.12</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.lmax</groupId> <groupId>com.lmax</groupId>
@@ -65,6 +65,18 @@
<version>1.1.1</version> <version>1.1.1</version>
</dependency> </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.25.3</version>
</dependency>
<dependency> <dependency>
<groupId>io.netty</groupId> <groupId>io.netty</groupId>
<artifactId>netty-common</artifactId> <artifactId>netty-common</artifactId>
@@ -112,9 +124,7 @@
<artifactId>netty-transport-native-epoll</artifactId> <artifactId>netty-transport-native-epoll</artifactId>
<version>${netty.version}</version> <version>${netty.version}</version>
<classifier>linux-x86_64</classifier> <classifier>linux-x86_64</classifier>
<!-- <!-- <classifier>linux-aarch_64</classifier>-->
<classifier>${os.detected.name}-${os.detected.arch}</classifier>
-->
</dependency> </dependency>
<dependency> <dependency>
@@ -129,37 +139,18 @@
<version>3.11.5</version> <version>3.11.5</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/com.xiaoleilu/hutool -->
<dependency> <dependency>
<groupId>com.xiaoleilu</groupId> <groupId>cn.hutool</groupId>
<artifactId>hutool</artifactId> <artifactId>hutool-all</artifactId>
<version>2.15.11</version> <version>5.8.26</version>
</dependency> </dependency>
<!-- Test dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency> <dependency>
<groupId>com.mchange</groupId> <groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId> <artifactId>c3p0</artifactId>
<version>0.9.5.4</version> <version>0.9.5.4</version>
</dependency> </dependency>
<!-- needs extra dependencies: objenesis & hamcrest -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.9.0</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.fusesource.mqtt-client</groupId> <groupId>org.fusesource.mqtt-client</groupId>
<artifactId>mqtt-client</artifactId> <artifactId>mqtt-client</artifactId>
@@ -169,29 +160,7 @@
<dependency> <dependency>
<groupId>org.eclipse.paho</groupId> <groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId> <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.1</version> <version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-client</artifactId>
<version>9.2.0.M1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<!-- use 2.6.0 for Java 7 projects -->
<version>2.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.191</version>
<scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
@@ -214,14 +183,12 @@
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
<dependency> <dependency>
<groupId>com.squareup.okhttp3</groupId> <groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId> <artifactId>okhttp</artifactId>
<version>3.13.1</version> <version>4.12.0</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.flywaydb/flyway-core -->
<dependency> <dependency>
<groupId>org.flywaydb</groupId> <groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId> <artifactId>flyway-core</artifactId>
@@ -34,6 +34,7 @@ public class PushMessage {
public String voipDeviceToken; public String voipDeviceToken;
public boolean isHiddenDetail; public boolean isHiddenDetail;
public String language; public String language;
public boolean republish;
public long messageId; public long messageId;
public PushMessage(String sender, int conversationType, String target, int line, int messageContentType, long serverTime, String senderName, String senderPortrait, String targetName, String targetPortrait, int unReceivedMsg, int mentionedType, boolean isHiddenDetail, String language) { public PushMessage(String sender, int conversationType, String target, int line, int messageContentType, long serverTime, String senderName, String senderPortrait, String targetName, String targetPortrait, int unReceivedMsg, int mentionedType, boolean isHiddenDetail, String language) {
@@ -65,6 +66,7 @@ public class PushMessage {
this.mentionedType = mentionedType; this.mentionedType = mentionedType;
this.isHiddenDetail = isHiddenDetail; this.isHiddenDetail = isHiddenDetail;
this.language = language; this.language = language;
this.republish = messageContentType == 80 || messageContentType == 81;
} }
public PushMessage(String sender, String target, long serverTime, String senderName, int unReceivedMsg, String language, int pushMessageType) { public PushMessage(String sender, String target, long serverTime, String senderName, int unReceivedMsg, String language, int pushMessageType) {
this.sender = sender; this.sender = sender;
@@ -24,8 +24,7 @@ import win.liyufan.im.Utility;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import static io.moquette.BrokerConstants.PUSH_ANDROID_SERVER_ADDRESS; import static io.moquette.BrokerConstants.*;
import static io.moquette.BrokerConstants.PUSH_IOS_SERVER_ADDRESS;
import static win.liyufan.im.HttpUtils.HttpPostType.POST_TYPE_Push; import static win.liyufan.im.HttpUtils.HttpPostType.POST_TYPE_Push;
public class PushServer { public class PushServer {
@@ -47,6 +46,7 @@ public class PushServer {
private String androidPushServerUrl; private String androidPushServerUrl;
private String iOSPushServerUrl; private String iOSPushServerUrl;
private String harmonyPushServerUrl;
private PushServer() { private PushServer() {
} }
@@ -59,6 +59,7 @@ public class PushServer {
this.sessionsStore = sessionsStore; this.sessionsStore = sessionsStore;
this.androidPushServerUrl = config.getProperty(PUSH_ANDROID_SERVER_ADDRESS); this.androidPushServerUrl = config.getProperty(PUSH_ANDROID_SERVER_ADDRESS);
this.iOSPushServerUrl = config.getProperty(PUSH_IOS_SERVER_ADDRESS); this.iOSPushServerUrl = config.getProperty(PUSH_IOS_SERVER_ADDRESS);
this.harmonyPushServerUrl = config.getProperty(PUSH_HARMONY_SERVER_ADDRESS);
} }
public void pushMessage(PushMessage pushMessage, String deviceId, String pushContent) { public void pushMessage(PushMessage pushMessage, String deviceId, String pushContent) {
@@ -95,11 +96,19 @@ public class PushServer {
pushMessage.deviceToken = session.getDeviceToken(); pushMessage.deviceToken = session.getDeviceToken();
pushMessage.unReceivedMsg = badge; pushMessage.unReceivedMsg = badge;
pushMessage.userId = session.getUsername(); pushMessage.userId = session.getUsername();
if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS || session.getPlatform() == ProtoConstants.Platform.Platform_Android) { if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS ||
session.getPlatform() == ProtoConstants.Platform.Platform_iPad ||
session.getPlatform() == ProtoConstants.Platform.Platform_Android ||
session.getPlatform() == ProtoConstants.Platform.Platform_APad ||
session.getPlatform() == ProtoConstants.Platform.Platform_Harmony ||
session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyPad
) {
String url = androidPushServerUrl; String url = androidPushServerUrl;
if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS) { if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS || session.getPlatform() == ProtoConstants.Platform.Platform_iPad) {
url = iOSPushServerUrl; url = iOSPushServerUrl;
pushMessage.voipDeviceToken = session.getVoipDeviceToken(); pushMessage.voipDeviceToken = session.getVoipDeviceToken();
} else if (session.getPlatform() == ProtoConstants.Platform.Platform_Harmony || session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyPad) {
url = harmonyPushServerUrl;
} }
HttpUtils.httpJsonPost(url, gson.toJson(pushMessage, pushMessage.getClass()), POST_TYPE_Push); HttpUtils.httpJsonPost(url, gson.toJson(pushMessage, pushMessage.getClass()), POST_TYPE_Push);
} else { } else {
@@ -1,8 +1,6 @@
package com.xiaoleilu.loServer; package com.xiaoleilu.loServer;
import com.xiaoleilu.hutool.log.Log; import cn.hutool.core.date.DateUtil;
import com.xiaoleilu.hutool.log.StaticLog;
import com.xiaoleilu.hutool.util.DateUtil;
import com.xiaoleilu.loServer.action.Action; import com.xiaoleilu.loServer.action.Action;
import com.xiaoleilu.loServer.action.ClassUtil; import com.xiaoleilu.loServer.action.ClassUtil;
import com.xiaoleilu.loServer.annotation.Route; import com.xiaoleilu.loServer.annotation.Route;
@@ -1,6 +1,6 @@
package com.xiaoleilu.loServer; package com.xiaoleilu.loServer;
import com.xiaoleilu.hutool.util.DateUtil; import cn.hutool.core.date.DateUtil;
import com.xiaoleilu.loServer.action.Action; import com.xiaoleilu.loServer.action.Action;
import com.xiaoleilu.loServer.annotation.Route; import com.xiaoleilu.loServer.annotation.Route;
import com.xiaoleilu.loServer.handler.AdminActionHandler; import com.xiaoleilu.loServer.handler.AdminActionHandler;
@@ -5,11 +5,9 @@ import java.nio.charset.Charset;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import com.xiaoleilu.hutool.lang.Singleton; import cn.hutool.core.io.FileUtil;
import com.xiaoleilu.hutool.log.Log; import cn.hutool.core.lang.Singleton;
import com.xiaoleilu.hutool.log.StaticLog; import cn.hutool.core.util.StrUtil;
import com.xiaoleilu.hutool.util.FileUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import com.xiaoleilu.loServer.action.Action; import com.xiaoleilu.loServer.action.Action;
import com.xiaoleilu.loServer.action.DefaultIndexAction; import com.xiaoleilu.loServer.action.DefaultIndexAction;
import com.xiaoleilu.loServer.action.UnknownErrorAction; import com.xiaoleilu.loServer.action.UnknownErrorAction;
@@ -189,7 +187,7 @@ public class ServerSetting {
* @param filterClass Filter类 * @param filterClass Filter类
*/ */
public static void setFilter(String path, Class<? extends Filter> filterClass) { public static void setFilter(String path, Class<? extends Filter> filterClass) {
setFilter(path, (Filter)Singleton.get(filterClass)); setFilter(path, (Filter) Singleton.get(filterClass));
} }
//----------------------------------------------------------------------------------------------- Filter end //----------------------------------------------------------------------------------------------- Filter end
@@ -47,6 +47,8 @@ abstract public class Action {
protected static RateLimiter robotLimiter = null; protected static RateLimiter robotLimiter = null;
protected static RateLimiter channelLimiter = null; protected static RateLimiter channelLimiter = null;
protected static boolean closeApiVersion = false;
public static void init(IConfig config) { public static void init(IConfig config) {
int adminRate = 10000; int adminRate = 10000;
int robotRate = 1000; int robotRate = 1000;
@@ -70,6 +72,11 @@ abstract public class Action {
adminLimiter = new RateLimiter(10, adminRate); adminLimiter = new RateLimiter(10, adminRate);
robotLimiter = new RateLimiter(10, robotRate); robotLimiter = new RateLimiter(10, robotRate);
channelLimiter = new RateLimiter(10, channelRate); channelLimiter = new RateLimiter(10, channelRate);
try {
closeApiVersion = Boolean.parseBoolean(config.getProperty(HTTP_CLOSE_API_VERSION, "false"));
} catch (Exception e) {
}
} }
protected class Result { protected class Result {
@@ -31,6 +31,11 @@ public class CheckTokenAction extends Action {
@Override @Override
public boolean action(Request request, Response response) { public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) { if (request.getNettyRequest() instanceof FullHttpRequest) {
if(closeApiVersion) {
response.sendError(HttpResponseStatus.NOT_FOUND, "404 Not found!");
return true;
}
response.setStatus(HttpResponseStatus.OK); response.setStatus(HttpResponseStatus.OK);
String userId = request.getParam("userId"); String userId = request.getParam("userId");
String clientId = request.getParam("clientId"); String clientId = request.getParam("clientId");
@@ -8,13 +8,11 @@ import java.util.Date;
import java.util.Locale; import java.util.Locale;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.HazelcastInstance;
import com.xiaoleilu.hutool.log.Log;
import com.xiaoleilu.hutool.log.StaticLog;
import com.xiaoleilu.hutool.util.DateUtil;
import com.xiaoleilu.hutool.util.FileUtil;
import com.xiaoleilu.hutool.util.ReUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import com.xiaoleilu.loServer.ServerSetting; import com.xiaoleilu.loServer.ServerSetting;
import com.xiaoleilu.loServer.handler.Request; import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response; import com.xiaoleilu.loServer.handler.Response;
@@ -24,6 +22,8 @@ import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpResponseStatus;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import static cn.hutool.core.date.DatePattern.HTTP_DATETIME_PATTERN;
/** /**
* 默认的主页Action,当访问主页且没有定义主页Action时,调用此Action * 默认的主页Action,当访问主页且没有定义主页Action时,调用此Action
* *
@@ -96,7 +96,7 @@ public class FileAction extends Action {
} }
private static final Pattern INSECURE_URI = Pattern.compile(".*[<>&\"].*"); private static final Pattern INSECURE_URI = Pattern.compile(".*[<>&\"].*");
private static final SimpleDateFormat HTTP_DATE_FORMATER = new SimpleDateFormat(DateUtil.HTTP_DATETIME_PATTERN, Locale.US); private static final SimpleDateFormat HTTP_DATE_FORMATER = new SimpleDateFormat(HTTP_DATETIME_PATTERN, Locale.US);
/** /**
@@ -1,9 +1,6 @@
package com.xiaoleilu.loServer.action; package com.xiaoleilu.loServer.action;
import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.HazelcastInstance;
import com.xiaoleilu.hutool.log.Log;
import com.xiaoleilu.hutool.log.StaticLog;
import com.xiaoleilu.hutool.util.StrUtil;
import com.xiaoleilu.loServer.handler.Request; import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response; import com.xiaoleilu.loServer.handler.Response;
import io.moquette.spi.IMessagesStore; import io.moquette.spi.IMessagesStore;
@@ -4,9 +4,6 @@ import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.HazelcastInstance;
import com.xiaoleilu.hutool.log.Log;
import com.xiaoleilu.hutool.log.StaticLog;
import com.xiaoleilu.hutool.util.StrUtil;
import com.xiaoleilu.loServer.handler.Request; import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response; import com.xiaoleilu.loServer.handler.Response;
@@ -30,8 +30,12 @@ public class VersionAction extends Action {
@Override @Override
public boolean action(Request request, Response response) { public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) { if (request.getNettyRequest() instanceof FullHttpRequest) {
response.setStatus(HttpResponseStatus.OK); if(closeApiVersion) {
response.sendError(HttpResponseStatus.NOT_FOUND, "404 Not found!");
return true;
}
response.setStatus(HttpResponseStatus.OK);
try { try {
response.setContent(Utility.formatJson(gson.toJson(GitRepositoryState.getGitRepositoryState()))); response.setContent(Utility.formatJson(gson.toJson(GitRepositoryState.getGitRepositoryState())));
@@ -48,10 +48,6 @@ public class CreateChatroomAction extends AdminAction {
inputCreateChatroom.setChatroomId(messagesStore.getShortUUID()); inputCreateChatroom.setChatroomId(messagesStore.getShortUUID());
} }
if (inputCreateChatroom.getPortrait() == null || inputCreateChatroom.getPortrait().length() == 0) {
inputCreateChatroom.setPortrait("https://avatars.io/gravatar/" + inputCreateChatroom.getChatroomId());
}
WFCMessage.ChatroomInfo info = inputCreateChatroom.toChatroomInfo(); WFCMessage.ChatroomInfo info = inputCreateChatroom.toChatroomInfo();
messagesStore.createChatroom(inputCreateChatroom.getChatroomId(), info); messagesStore.createChatroom(inputCreateChatroom.getChatroomId(), info);
setResponseContent(RestResult.ok(new OutputCreateChatroom(inputCreateChatroom.getChatroomId())), response); setResponseContent(RestResult.ok(new OutputCreateChatroom(inputCreateChatroom.getChatroomId())), response);
@@ -45,23 +45,13 @@ public class CreateRobotAction extends AdminAction {
if (inputCreateRobot != null if (inputCreateRobot != null
&& !StringUtil.isNullOrEmpty(inputCreateRobot.getName())) { && !StringUtil.isNullOrEmpty(inputCreateRobot.getName())) {
if(StringUtil.isNullOrEmpty(inputCreateRobot.getPassword())) {
inputCreateRobot.setPassword(UUIDGenerator.getUUID());
}
if(StringUtil.isNullOrEmpty(inputCreateRobot.getUserId())) { if(StringUtil.isNullOrEmpty(inputCreateRobot.getUserId())) {
inputCreateRobot.setUserId(messagesStore.getShortUUID()); inputCreateRobot.setUserId(messagesStore.getShortUUID());
} }
if (inputCreateRobot.getPortrait() == null || inputCreateRobot.getPortrait().length() == 0) {
inputCreateRobot.setPortrait("https://avatars.io/gravatar/" + inputCreateRobot.getUserId());
}
WFCMessage.User newUser = inputCreateRobot.toUser(); WFCMessage.User newUser = inputCreateRobot.toUser();
try { try {
messagesStore.addUserInfo(newUser, inputCreateRobot.getPassword()); messagesStore.addUserInfo(newUser);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ADMIN_API_Exception); Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ADMIN_API_Exception);
@@ -47,10 +47,6 @@ public class CreateUserAction extends AdminAction {
&& !StringUtil.isNullOrEmpty(inputCreateUser.getName()) && !StringUtil.isNullOrEmpty(inputCreateUser.getName())
&& (inputCreateUser.getType() == ProtoConstants.UserType.UserType_Normal || inputCreateUser.getType() == ProtoConstants.UserType.UserType_Admin || inputCreateUser.getType() == ProtoConstants.UserType.UserType_Super_Admin)) { && (inputCreateUser.getType() == ProtoConstants.UserType.UserType_Normal || inputCreateUser.getType() == ProtoConstants.UserType.UserType_Admin || inputCreateUser.getType() == ProtoConstants.UserType.UserType_Super_Admin)) {
if(StringUtil.isNullOrEmpty(inputCreateUser.getPassword())) {
inputCreateUser.setPassword(UUIDGenerator.getUUID());
}
if(StringUtil.isNullOrEmpty(inputCreateUser.getUserId())) { if(StringUtil.isNullOrEmpty(inputCreateUser.getUserId())) {
inputCreateUser.setUserId(messagesStore.getShortUUID()); inputCreateUser.setUserId(messagesStore.getShortUUID());
} }
@@ -85,7 +81,7 @@ public class CreateUserAction extends AdminAction {
try { try {
messagesStore.addUserInfo(newUserBuilder.build(), inputCreateUser.getPassword()); messagesStore.addUserInfo(newUserBuilder.build());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ADMIN_API_Exception); Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ADMIN_API_Exception);
@@ -0,0 +1,61 @@
/*
* 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 com.xiaoleilu.loServer.action.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.*;
import cn.wildfirechat.proto.WFCMessage;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.annotation.HttpMethod;
import com.xiaoleilu.loServer.annotation.Route;
import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.internal.StringUtil;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@Route(APIPath.User_Batch_Get_Infos)
@HttpMethod("POST")
public class GetBatchUserAction extends AdminAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputStringList inputUserId = getRequestBody(request.getNettyRequest(), InputStringList.class);
if (inputUserId != null && inputUserId.getList() != null && !inputUserId.getList().isEmpty()) {
OutputUserInfoList res = new OutputUserInfoList();
res.userInfos = new ArrayList<>();
for (String userId : inputUserId.getList()) {
WFCMessage.User user = messagesStore.getUserInfo(userId);
if(user == null || StringUtil.isNullOrEmpty(user.getName())) {
continue;
}
InputOutputUserInfo inputOutputUserInfo = InputOutputUserInfo.fromPbUser(user);
res.userInfos.add(inputOutputUserInfo);
}
RestResult result = RestResult.ok(res);
setResponseContent(result, response);
} else {
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
}
}
return true;
}
}
@@ -53,10 +53,17 @@ public class GetGroupInfoAction extends AdminAction {
pojoGroupInfo.setPortrait(groupInfo.getPortrait()); pojoGroupInfo.setPortrait(groupInfo.getPortrait());
pojoGroupInfo.setTarget_id(groupInfo.getTargetId()); pojoGroupInfo.setTarget_id(groupInfo.getTargetId());
pojoGroupInfo.setType(groupInfo.getType()); pojoGroupInfo.setType(groupInfo.getType());
pojoGroupInfo.setMember_count(groupInfo.getMemberCount());
pojoGroupInfo.setMute(groupInfo.getMute()); pojoGroupInfo.setMute(groupInfo.getMute());
pojoGroupInfo.setJoin_type(groupInfo.getJoinType()); pojoGroupInfo.setJoin_type(groupInfo.getJoinType());
pojoGroupInfo.setPrivate_chat(groupInfo.getPrivateChat()); pojoGroupInfo.setPrivate_chat(groupInfo.getPrivateChat());
pojoGroupInfo.setSearchable(groupInfo.getSearchable()); pojoGroupInfo.setSearchable(groupInfo.getSearchable());
pojoGroupInfo.setMax_member_count(groupInfo.getMemberCount());
pojoGroupInfo.setHistory_message(groupInfo.getHistoryMessage());
pojoGroupInfo.setSuper_group(groupInfo.getSuperGroup()>0);
pojoGroupInfo.setDeleted(groupInfo.getDeleted()>0);
pojoGroupInfo.setUpdate_dt(groupInfo.getUpdateDt());
pojoGroupInfo.setMember_update_dt(groupInfo.getMemberUpdateDt());
result = RestResult.ok(pojoGroupInfo); result = RestResult.ok(pojoGroupInfo);
} }
setResponseContent(result, response); setResponseContent(result, response);
@@ -0,0 +1,47 @@
/*
* 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 com.xiaoleilu.loServer.action.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.*;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.annotation.HttpMethod;
import com.xiaoleilu.loServer.annotation.Route;
import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response;
import io.moquette.persistence.MemorySessionStore;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.util.internal.StringUtil;
import java.util.Collection;
@Route(APIPath.User_Online_List)
@HttpMethod("POST")
public class GetOnlineUserAction extends AdminAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
GetOnlineUserRequest getOnlineUserRequest = getRequestBody(request.getNettyRequest(), GetOnlineUserRequest.class);
if (getOnlineUserRequest.nodeId == 1) {
GetOnlineUserResult result = messagesStore.getOnlineUsers(getOnlineUserRequest.offset, getOnlineUserRequest.count);
setResponseContent(RestResult.ok(result), response);
} else {
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
}
}
return true;
}
}
@@ -0,0 +1,61 @@
/*
* 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 com.xiaoleilu.loServer.action.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputGetChatroomInfo;
import cn.wildfirechat.pojos.InputUserId;
import cn.wildfirechat.pojos.OutputStringList;
import cn.wildfirechat.pojos.OutputUserChatroom;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.annotation.HttpMethod;
import com.xiaoleilu.loServer.annotation.Route;
import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response;
import io.moquette.persistence.UserClientEntry;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.util.internal.StringUtil;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@Route(APIPath.Chatroom_GetUserChatroom)
@HttpMethod("POST")
public class GetUserChatroomAction extends AdminAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputUserId inputUserId = getRequestBody(request.getNettyRequest(), InputUserId.class);
String userId = inputUserId.getUserId();
if (!StringUtil.isNullOrEmpty(userId)) {
OutputUserChatroom outputUserChatroom = messagesStore.getUserChatroom(userId);
RestResult result;
if (outputUserChatroom != null) {
result = RestResult.ok(outputUserChatroom);
} else {
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
}
setResponseContent(result, response);
} else {
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
}
}
return true;
}
}
@@ -0,0 +1,55 @@
/*
* 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 com.xiaoleilu.loServer.action.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputGetUserGroupByType;
import cn.wildfirechat.pojos.InputUserId;
import cn.wildfirechat.pojos.OutputGroupIds;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.annotation.HttpMethod;
import com.xiaoleilu.loServer.annotation.Route;
import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.util.internal.StringUtil;
import java.util.ArrayList;
import java.util.Set;
@Route(APIPath.Get_User_Groups_By_Type)
@HttpMethod("POST")
public class GetUserGroupsByTypeAction extends AdminAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputGetUserGroupByType input = getRequestBody(request.getNettyRequest(), InputGetUserGroupByType.class);
if (input != null
&& (!StringUtil.isNullOrEmpty(input.getUserId()))) {
Set<String> groupIds = messagesStore.getUserGroupIds(input.getUserId(), input.getGroupMemberTypes());
OutputGroupIds outputGroupIds = new OutputGroupIds();
outputGroupIds.setGroupIds(new ArrayList<>(groupIds));
RestResult result = RestResult.ok(outputGroupIds);
setResponseContent(result, response);
} else {
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
}
}
return true;
}
}
@@ -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 com.xiaoleilu.loServer.action.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.GetOnlineUserCountResult;
import cn.wildfirechat.pojos.GetUserSessionResult;
import cn.wildfirechat.pojos.InputUserId;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.annotation.HttpMethod;
import com.xiaoleilu.loServer.annotation.Route;
import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response;
import io.moquette.persistence.MemorySessionStore;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.util.internal.StringUtil;
import java.util.Collection;
@Route(APIPath.User_Online_Count)
@HttpMethod("POST")
public class GetUserOnlineCountAction extends AdminAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
int count = messagesStore.getOnlineUserCount();
GetOnlineUserCountResult result = new GetOnlineUserCountResult();
GetOnlineUserCountResult.Node node = new GetOnlineUserCountResult.Node();
node.node = 1;
node.count = count;
result.add(node);
setResponseContent(RestResult.ok(result), response);
}
return true;
}
}
@@ -0,0 +1,57 @@
/*
* 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 com.xiaoleilu.loServer.action.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.GetUserSessionResult;
import cn.wildfirechat.pojos.InputGetChatroomInfo;
import cn.wildfirechat.pojos.InputUserId;
import cn.wildfirechat.pojos.OutputStringList;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.annotation.HttpMethod;
import com.xiaoleilu.loServer.annotation.Route;
import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response;
import io.moquette.persistence.MemorySessionStore;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.util.internal.StringUtil;
import java.util.Collection;
@Route(APIPath.User_Session_List)
@HttpMethod("POST")
public class GetUserSessionsAction extends AdminAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputUserId inputUserId = getRequestBody(request.getNettyRequest(), InputUserId.class);
String userId = inputUserId.getUserId();
if (!StringUtil.isNullOrEmpty(userId)) {
Collection<MemorySessionStore.Session> sessions = sessionsStore.sessionForUser(userId);
GetUserSessionResult result = new GetUserSessionResult();
for (MemorySessionStore.Session session : sessions) {
boolean isOnline = sessionsStore.isClientOnline(session.getClientID());
result.userSessions.add(new GetUserSessionResult.UserSession(session.getUsername(), session.getClientID(), session.getPlatform(), session.getPushType(), session.getDeviceToken(), session.getVoipDeviceToken(), isOnline));
}
setResponseContent(RestResult.ok(result), response);
} else {
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
}
}
return true;
}
}
@@ -0,0 +1,66 @@
/*
* 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 com.xiaoleilu.loServer.action.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputGetUserInfo;
import cn.wildfirechat.pojos.InputOutputUserInfo;
import cn.wildfirechat.pojos.OutputUserInfoList;
import cn.wildfirechat.proto.WFCMessage;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.annotation.HttpMethod;
import com.xiaoleilu.loServer.annotation.Route;
import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.util.internal.StringUtil;
import java.util.ArrayList;
import java.util.List;
@Route(APIPath.User_Get_Email_Info)
@HttpMethod("POST")
public class GetUsersByEmailAction extends AdminAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
String email = getRequestBody(request.getNettyRequest(), String.class);
if (!StringUtil.isNullOrEmpty(email)) {
List<WFCMessage.User> users = messagesStore.getUserInfosByEmail(email);
List<InputOutputUserInfo> list = new ArrayList<>();
for (WFCMessage.User user : users) {
list.add(InputOutputUserInfo.fromPbUser(user));
}
RestResult result;
if (list.isEmpty()) {
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
} else {
OutputUserInfoList outputUserInfoList = new OutputUserInfoList();
outputUserInfoList.userInfos = list;
result = RestResult.ok(outputUserInfoList);
}
setResponseContent(result, response);
} else {
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
}
}
return true;
}
}
@@ -52,10 +52,17 @@ public class GetGroupInfoAction extends RobotAction {
pojoGroupInfo.setPortrait(groupInfo.getPortrait()); pojoGroupInfo.setPortrait(groupInfo.getPortrait());
pojoGroupInfo.setTarget_id(groupInfo.getTargetId()); pojoGroupInfo.setTarget_id(groupInfo.getTargetId());
pojoGroupInfo.setType(groupInfo.getType()); pojoGroupInfo.setType(groupInfo.getType());
pojoGroupInfo.setMember_count(groupInfo.getMemberCount());
pojoGroupInfo.setMute(groupInfo.getMute()); pojoGroupInfo.setMute(groupInfo.getMute());
pojoGroupInfo.setJoin_type(groupInfo.getJoinType()); pojoGroupInfo.setJoin_type(groupInfo.getJoinType());
pojoGroupInfo.setPrivate_chat(groupInfo.getPrivateChat()); pojoGroupInfo.setPrivate_chat(groupInfo.getPrivateChat());
pojoGroupInfo.setSearchable(groupInfo.getSearchable()); pojoGroupInfo.setSearchable(groupInfo.getSearchable());
pojoGroupInfo.setMax_member_count(groupInfo.getMemberCount());
pojoGroupInfo.setHistory_message(groupInfo.getHistoryMessage());
pojoGroupInfo.setSuper_group(groupInfo.getSuperGroup()>0);
pojoGroupInfo.setDeleted(groupInfo.getDeleted()>0);
pojoGroupInfo.setUpdate_dt(groupInfo.getUpdateDt());
pojoGroupInfo.setMember_update_dt(groupInfo.getMemberUpdateDt());
result = RestResult.ok(pojoGroupInfo); result = RestResult.ok(pojoGroupInfo);
} }
setResponseContent(result, response); setResponseContent(result, response);
@@ -80,6 +80,7 @@ public class UpdateProfileAction extends RobotAction {
RestResult result = RestResult.ok(); RestResult result = RestResult.ok();
if(modified) { if(modified) {
try { try {
builder.setUpdateDt(System.currentTimeMillis());
messagesStore.updateUserInfo(builder.build()); messagesStore.updateUserInfo(builder.build());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@@ -1,31 +1,32 @@
package com.xiaoleilu.loServer.exception; package com.xiaoleilu.loServer.exception;
import com.xiaoleilu.hutool.util.StrUtil;
import cn.hutool.core.util.StrUtil;
/**
* 设置异常 /**
* @author xiaoleilu * 设置异常
*/ * @author xiaoleilu
public class ServerSettingException extends RuntimeException{ */
private static final long serialVersionUID = -4134588858314744501L; public class ServerSettingException extends RuntimeException{
private static final long serialVersionUID = -4134588858314744501L;
public ServerSettingException(Throwable e) {
super(e); public ServerSettingException(Throwable e) {
} super(e);
}
public ServerSettingException(String message) {
super(message); public ServerSettingException(String message) {
} super(message);
}
public ServerSettingException(String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params)); public ServerSettingException(String messageTemplate, Object... params) {
} super(StrUtil.format(messageTemplate, params));
}
public ServerSettingException(String message, Throwable throwable) {
super(message, throwable); public ServerSettingException(String message, Throwable throwable) {
} super(message, throwable);
}
public ServerSettingException(Throwable throwable, String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params), throwable); public ServerSettingException(Throwable throwable, String messageTemplate, Object... params) {
} super(StrUtil.format(messageTemplate, params), throwable);
} }
}
@@ -1,7 +1,7 @@
package com.xiaoleilu.loServer.handler; package com.xiaoleilu.loServer.handler;
import cn.hutool.core.lang.Singleton;
import cn.wildfirechat.common.IMExceptionEvent; import cn.wildfirechat.common.IMExceptionEvent;
import com.xiaoleilu.hutool.lang.Singleton;
import com.xiaoleilu.loServer.ServerSetting; import com.xiaoleilu.loServer.ServerSetting;
import com.xiaoleilu.loServer.action.Action; import com.xiaoleilu.loServer.action.Action;
import com.xiaoleilu.loServer.action.UnknownErrorAction; import com.xiaoleilu.loServer.action.UnknownErrorAction;
@@ -8,7 +8,6 @@
package com.xiaoleilu.loServer.handler; package com.xiaoleilu.loServer.handler;
import com.xiaoleilu.hutool.lang.Singleton;
import com.xiaoleilu.loServer.ServerSetting; import com.xiaoleilu.loServer.ServerSetting;
import com.xiaoleilu.loServer.action.Action; import com.xiaoleilu.loServer.action.Action;
import com.xiaoleilu.loServer.action.FileAction; import com.xiaoleilu.loServer.action.FileAction;
@@ -1,28 +1,27 @@
package com.xiaoleilu.loServer.handler; package com.xiaoleilu.loServer.handler;
import com.xiaoleilu.hutool.log.StaticLog; import cn.hutool.log.StaticLog;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPromise;
import io.netty.channel.ChannelPromise; import io.netty.channel.FileRegion;
import io.netty.channel.FileRegion; import io.netty.handler.codec.http.DefaultHttpResponse;
import io.netty.handler.codec.http.DefaultHttpResponse; import io.netty.handler.codec.http.HttpContentCompressor;
import io.netty.handler.codec.http.HttpContentCompressor;
/**
/** * 解决大文件传输与Gzip压缩冲突问题
* 解决大文件传输与Gzip压缩冲突问题 * @author Looly
* @author Looly *
* */
*/ public class HttpChunkContentCompressor extends HttpContentCompressor {
public class HttpChunkContentCompressor extends HttpContentCompressor { @Override
@Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { StaticLog.debug("Write object [{}]", msg);
StaticLog.debug("Write object [{}]", msg);
if (msg instanceof FileRegion || msg instanceof DefaultHttpResponse) {
if (msg instanceof FileRegion || msg instanceof DefaultHttpResponse) { //文件传输不经过Gzip压缩
//文件传输不经过Gzip压缩 ctx.write(msg, promise);
ctx.write(msg, promise); }else{
}else{ super.write(ctx, msg, promise);
super.write(ctx, msg, promise); }
} }
} }
}
@@ -1,7 +1,6 @@
package com.xiaoleilu.loServer.handler; package com.xiaoleilu.loServer.handler;
import io.netty.util.internal.StringUtil; import io.netty.util.internal.StringUtil;
import com.xiaoleilu.hutool.util.FileUtil;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
@@ -8,7 +8,6 @@
package com.xiaoleilu.loServer.handler; package com.xiaoleilu.loServer.handler;
import com.xiaoleilu.hutool.lang.Singleton;
import com.xiaoleilu.loServer.ServerSetting; import com.xiaoleilu.loServer.ServerSetting;
import com.xiaoleilu.loServer.action.Action; import com.xiaoleilu.loServer.action.Action;
import com.xiaoleilu.loServer.action.FileAction; import com.xiaoleilu.loServer.action.FileAction;
@@ -10,15 +10,12 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import com.xiaoleilu.hutool.http.HttpUtil; import cn.hutool.core.convert.Convert;
import com.xiaoleilu.hutool.lang.Conver; import cn.hutool.core.date.DateUtil;
import com.xiaoleilu.hutool.log.Log; import cn.hutool.core.net.NetUtil;
import com.xiaoleilu.hutool.log.StaticLog; import cn.hutool.core.util.CharsetUtil;
import com.xiaoleilu.hutool.util.CharsetUtil; import cn.hutool.core.util.StrUtil;
import com.xiaoleilu.hutool.util.DateUtil; import cn.hutool.core.util.URLUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import com.xiaoleilu.hutool.util.URLUtil;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpHeaderNames;
@@ -261,7 +258,7 @@ public class Request {
* @return 获得Integer类型请求参数 * @return 获得Integer类型请求参数
*/ */
public Integer getIntParam(String name, Integer defaultValue) { public Integer getIntParam(String name, Integer defaultValue) {
return Conver.toInt(getParam(name), defaultValue); return Convert.toInt(getParam(name), defaultValue);
} }
/** /**
@@ -270,7 +267,7 @@ public class Request {
* @return 获得long类型请求参数 * @return 获得long类型请求参数
*/ */
public Long getLongParam(String name, Long defaultValue) { public Long getLongParam(String name, Long defaultValue) {
return Conver.toLong(getParam(name), defaultValue); return Convert.toLong(getParam(name), defaultValue);
} }
/** /**
@@ -279,7 +276,7 @@ public class Request {
* @return 获得Double类型请求参数 * @return 获得Double类型请求参数
*/ */
public Double getDoubleParam(String name, Double defaultValue) { public Double getDoubleParam(String name, Double defaultValue) {
return Conver.toDouble(getParam(name), defaultValue); return Convert.toDouble(getParam(name), defaultValue);
} }
/** /**
@@ -288,7 +285,7 @@ public class Request {
* @return 获得Float类型请求参数 * @return 获得Float类型请求参数
*/ */
public Float getFloatParam(String name, Float defaultValue) { public Float getFloatParam(String name, Float defaultValue) {
return Conver.toFloat(getParam(name), defaultValue); return Convert.toFloat(getParam(name), defaultValue);
} }
/** /**
@@ -297,7 +294,7 @@ public class Request {
* @return 获得Boolean类型请求参数 * @return 获得Boolean类型请求参数
*/ */
public Boolean getBoolParam(String name, Boolean defaultValue) { public Boolean getBoolParam(String name, Boolean defaultValue) {
return Conver.toBool(getParam(name), defaultValue); return Convert.toBool(getParam(name), defaultValue);
} }
/** /**
@@ -477,7 +474,7 @@ public class Request {
protected void putIp(ChannelHandlerContext ctx) { protected void putIp(ChannelHandlerContext ctx) {
String ip = getHeader("X-Forwarded-For"); String ip = getHeader("X-Forwarded-For");
if (StrUtil.isNotBlank(ip)) { if (StrUtil.isNotBlank(ip)) {
ip = HttpUtil.getMultistageReverseProxyIp(ip); ip = NetUtil.getMultistageReverseProxyIp(ip);
} else { } else {
final InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress(); final InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
ip = insocket.getAddress().getHostAddress(); ip = insocket.getAddress().getHostAddress();
@@ -13,12 +13,9 @@ import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.TimeZone; import java.util.TimeZone;
import com.xiaoleilu.hutool.http.HttpUtil; import cn.hutool.core.date.DateUtil;
import com.xiaoleilu.hutool.log.Log; import cn.hutool.core.util.CharsetUtil;
import com.xiaoleilu.hutool.log.StaticLog; import cn.hutool.core.util.StrUtil;
import com.xiaoleilu.hutool.util.CharsetUtil;
import com.xiaoleilu.hutool.util.DateUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import com.xiaoleilu.loServer.ServerSetting; import com.xiaoleilu.loServer.ServerSetting;
import com.xiaoleilu.loServer.listener.FileProgressiveFutureListener; import com.xiaoleilu.loServer.listener.FileProgressiveFutureListener;
@@ -44,6 +41,8 @@ import io.netty.handler.codec.http.cookie.ServerCookieEncoder;
import org.apache.tika.Tika; import org.apache.tika.Tika;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import static cn.hutool.core.date.DatePattern.HTTP_DATETIME_PATTERN;
/** /**
* 响应对象 * 响应对象
* *
@@ -332,7 +331,7 @@ public class Response {
* @param httpCacheSeconds 缓存时间,单位秒 * @param httpCacheSeconds 缓存时间,单位秒
*/ */
public void setDateAndCache(long lastModify, int httpCacheSeconds) { public void setDateAndCache(long lastModify, int httpCacheSeconds) {
SimpleDateFormat formatter = new SimpleDateFormat(DateUtil.HTTP_DATETIME_PATTERN, Locale.US); SimpleDateFormat formatter = new SimpleDateFormat(HTTP_DATETIME_PATTERN, Locale.US);
formatter.setTimeZone(TimeZone.getTimeZone("GMT")); formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
// Date header // Date header
@@ -2,10 +2,7 @@ package com.xiaoleilu.loServer.listener;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import com.xiaoleilu.hutool.io.IoUtil; import cn.hutool.core.io.IoUtil;
import com.xiaoleilu.hutool.log.Log;
import com.xiaoleilu.hutool.log.StaticLog;
import io.netty.channel.ChannelProgressiveFuture; import io.netty.channel.ChannelProgressiveFuture;
import io.netty.channel.ChannelProgressiveFutureListener; import io.netty.channel.ChannelProgressiveFutureListener;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -90,6 +90,7 @@ public final class BrokerConstants {
public static final String PUSH_ANDROID_SERVER_ADDRESS = "push.android.server.address"; public static final String PUSH_ANDROID_SERVER_ADDRESS = "push.android.server.address";
public static final String PUSH_IOS_SERVER_ADDRESS = "push.ios.server.address"; public static final String PUSH_IOS_SERVER_ADDRESS = "push.ios.server.address";
public static final String PUSH_HARMONY_SERVER_ADDRESS = "push.harmony.server.address";
public static final String MONITOR_Exception_Event_Address = "monitor.exception_event_address"; public static final String MONITOR_Exception_Event_Address = "monitor.exception_event_address";
@@ -115,6 +116,8 @@ public final class BrokerConstants {
public static final String CONNECT_CLIENT_SIGNATURE_LIST = "connect.client_signature_list"; public static final String CONNECT_CLIENT_SIGNATURE_LIST = "connect.client_signature_list";
public static final String CONNECT_REJECT_EMPTY_SIGNATURE = "connect.reject_empty_signature"; public static final String CONNECT_REJECT_EMPTY_SIGNATURE = "connect.reject_empty_signature";
public static final String ID_USE_UUID = "id.use_uuid";
public static final String EMBED_DB_PROPERTY_NAME = "embed.db"; public static final String EMBED_DB_PROPERTY_NAME = "embed.db";
public static final String DB_AUTO_CLEAN_HISTORY_MESSAGES = "db.auto_clean_history_messages"; public static final String DB_AUTO_CLEAN_HISTORY_MESSAGES = "db.auto_clean_history_messages";
public static final String H2DB_PATH = "h2db.path"; public static final String H2DB_PATH = "h2db.path";
@@ -135,6 +138,7 @@ public final class BrokerConstants {
public static final String SERVER_MULTI_ENDPOINT = "server.multi_endpoint"; public static final String SERVER_MULTI_ENDPOINT = "server.multi_endpoint";
public static final String SERVER_MULTI_PC_ENDPOINT = "server.multi_pc_endpoint"; public static final String SERVER_MULTI_PC_ENDPOINT = "server.multi_pc_endpoint";
public static final String SERVER_MULTI_PAD_ENDPOINT = "server.multi_pad_endpoint";
public static final String SERVER_MULTI_PLATFROM_NOTIFICATION = "server.multi_platform_notification"; public static final String SERVER_MULTI_PLATFROM_NOTIFICATION = "server.multi_platform_notification";
public static final String SERVER_MOBILE_DEFAULT_SILENT_WHEN_PC_ONLINE = "server.mobile_default_silent_when_pc_online"; public static final String SERVER_MOBILE_DEFAULT_SILENT_WHEN_PC_ONLINE = "server.mobile_default_silent_when_pc_online";
public static final String SERVER_CLIENT_SUPPORT_KICKOFF_EVENT = "server.client_support_kickoff_event"; public static final String SERVER_CLIENT_SUPPORT_KICKOFF_EVENT = "server.client_support_kickoff_event";
@@ -148,35 +152,53 @@ public final class BrokerConstants {
public static final String MESSAGE_Disable_Stranger_Chat = "message.disable_stranger_chat"; public static final String MESSAGE_Disable_Stranger_Chat = "message.disable_stranger_chat";
public static final String MESSAGE_Allow_Stranger_Chat_List = "message.allow_stranger_chat_list"; public static final String MESSAGE_Allow_Stranger_Chat_List = "message.allow_stranger_chat_list";
public static final String MESSAGE_Allow_Stranger_Line = "message.allow_stranger_line";
public static final String MESSAGE_Blacklist_Strategy = "message.blacklist.strategy"; public static final String MESSAGE_Blacklist_Strategy = "message.blacklist.strategy";
public static final String MESSAGE_Blacklist_Allow_Send = "message.blacklist.allow_send_to_black";
public static final String MESSAGE_NO_Forward_Admin_Message = "message.no_forward_admin_message"; public static final String MESSAGE_NO_Forward_Admin_Message = "message.no_forward_admin_message";
public static final String MESSAGE_Push_Expired_Days = "message.push_expired_days";
public static final String MESSAGE_Force_Push_Types = "message.force_push_types";
public static final String MESSAGE_Forward_With_Client_Info = "message.forward_with_client_info"; public static final String MESSAGE_Forward_With_Client_Info = "message.forward_with_client_info";
public static final String BROADCAST_Target_From_User_Table = "message.broadcast.target_from_user_table";
public static final String ROBOT_Callback_With_Client_Info = "robot.callback_with_client_info"; public static final String ROBOT_Callback_With_Client_Info = "robot.callback_with_client_info";
public static final String CHANNEL_Callback_With_Client_Info = "channel.callback_with_client_info"; public static final String CHANNEL_Callback_With_Client_Info = "channel.callback_with_client_info";
public static final String CHANNEL_New_Callback_Feature = "channel.new_callback_feature";
public static final String FRIEND_Disable_Search = "friend.disable_search"; 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_NickName_Search = "friend.disable_nick_name_search";
public static final String FRIEND_Disable_UserId_Search = "friend.disable_user_id_search";
public static final String FRIEND_Disable_Friend_Request = "friend.disable_friend_request"; 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_Repeat_Request_Duration = "friend.repeat_request_duration";
public static final String FRIEND_Reject_Request_Duration = "friend.reject_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_Request_Expiration_Duration = "friend.request_expiration_duration";
public static final String FRIEND_Request_Rate_Limit = "friend.request_rate_limit";
public static final String FRIEND_Request_Robot_Auto_Accept = "friend.robot_auto_accept"; public static final String FRIEND_Request_Robot_Auto_Accept = "friend.robot_auto_accept";
public static final String CHATROOM_Participant_Idle_Time = "chatroom.participant_idle_time"; 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 CHATROOM_Rejoin_When_Active = "chatroom.rejoin_when_active";
public static final String CHATROOM_Create_When_Not_Exist = "chatroom.create_when_not_exist"; public static final String CHATROOM_Create_When_Not_Exist = "chatroom.create_when_not_exist";
public static final String CHATROOM_Kickoff_Other_Platform = "chatroom.kickoff_other_platform";
public static final String GROUP_Allow_Owner_Recall_Self_Msg = "group.allow_owner_recall_self_msg";
public static final String GROUP_Allow_Manager_Recall_Self_Msg = "group.allow_manager_recall_self_msg";
public static final String GROUP_Allow_Client_Custom_Operation_Notification = "group.allow_client_custom_operation_notification"; public static final String GROUP_Allow_Client_Custom_Operation_Notification = "group.allow_client_custom_operation_notification";
public static final String GROUP_Allow_Robot_Custom_Operation_Notification = "group.allow_robot_custom_operation_notificatio"; public static final String GROUP_Allow_Robot_Custom_Operation_Notification = "group.allow_robot_custom_operation_notificatio";
public static final String GROUP_Visible_Quit_Kickoff_Notification = "group.visible_quit_or_kickoff_notification"; public static final String GROUP_Visible_Quit_Kickoff_Notification = "group.visible_quit_or_kickoff_notification";
public static final String GROUP_Forbidden_Client_Operation = "group.forbidden_client_operation"; public static final String GROUP_Forbidden_Client_Operation = "group.forbidden_client_operation";
public static final String GROUP_Disable_Stranger_Invite = "group.disable_stranger_invite";
public static final String GROUP_INFO_MARK_DELETION = "group.enable_mark_deletion";
public static final String USER_HIDE_PROPERTIES = "user.hide_properties"; public static final String USER_HIDE_PROPERTIES = "user.hide_properties";
public static final String USER_KEEP_DISPLAY_NAME_WHEN_DESTROY = "user.keep_display_name_when_destroy"; public static final String USER_KEEP_DISPLAY_NAME_WHEN_DESTROY = "user.keep_display_name_when_destroy";
@@ -199,6 +221,9 @@ public final class BrokerConstants {
public static final String HTTP_CHANNEL_RATE_LIMIT = "http.channel.rate_limit"; public static final String HTTP_CHANNEL_RATE_LIMIT = "http.channel.rate_limit";
public static final String CLIENT_REQUEST_RATE_LIMIT = "client.request_rate_limit"; public static final String CLIENT_REQUEST_RATE_LIMIT = "client.request_rate_limit";
public static final String HTTP_CLOSE_API_VERSION = "http.close_api_version";
private BrokerConstants() { private BrokerConstants() {
} }
} }
@@ -24,7 +24,8 @@ public class AddFriendHandler extends GroupHandler<WFCMessage.AddFriendRequest>
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.AddFriendRequest request, Qos1PublishHandler.IMCallback callback) { public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.AddFriendRequest request, Qos1PublishHandler.IMCallback callback) {
long[] head = new long[1]; long[] head = new long[1];
boolean isAdmin = requestSourceType == ProtoConstants.RequestSourceType.Request_From_Admin; boolean isAdmin = requestSourceType == ProtoConstants.RequestSourceType.Request_From_Admin;
ErrorCode errorCode = m_messagesStore.saveAddFriendRequest(fromUser, request, head, isAdmin); boolean isRobot = requestSourceType == ProtoConstants.RequestSourceType.Request_From_Robot;
ErrorCode errorCode = m_messagesStore.saveAddFriendRequest(fromUser, request, head, isAdmin, isRobot);
if (errorCode == ERROR_CODE_SUCCESS) { if (errorCode == ERROR_CODE_SUCCESS) {
WFCMessage.User user = m_messagesStore.getUserInfo(request.getTargetUid()); WFCMessage.User user = m_messagesStore.getUserInfo(request.getTargetUid());
if (user != null && user.getType() == ProtoConstants.UserType.UserType_Normal) { if (user != null && user.getType() == ProtoConstants.UserType.UserType_Normal) {
@@ -43,7 +43,7 @@ public class AddGroupMember extends GroupHandler<WFCMessage.AddGroupMemberReques
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) { if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent()); sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
} else { } else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, getMemberIdList(request.getAddedMemberList())).getAddGroupNotifyContent(); WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, getMemberIdList(request.getAddedMemberList())).setExtra(request.getExtra()).getAddGroupNotifyContent();
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content); sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content);
} }
} }
@@ -27,7 +27,7 @@ public class CreateGroupHandler extends GroupHandler<WFCMessage.CreateGroupReque
if (!StringUtil.isNullOrEmpty(request.getGroup().getGroupInfo().getTargetId())) { if (!StringUtil.isNullOrEmpty(request.getGroup().getGroupInfo().getTargetId())) {
WFCMessage.GroupInfo existGroupInfo = m_messagesStore.getGroupInfo(request.getGroup().getGroupInfo().getTargetId()); WFCMessage.GroupInfo existGroupInfo = m_messagesStore.getGroupInfo(request.getGroup().getGroupInfo().getTargetId());
if (existGroupInfo != null) { if (existGroupInfo != null && existGroupInfo.getDeleted() == 0) {
return ErrorCode.ERROR_CODE_GROUP_ALREADY_EXIST; return ErrorCode.ERROR_CODE_GROUP_ALREADY_EXIST;
} }
} }
@@ -50,12 +50,20 @@ public class CreateGroupHandler extends GroupHandler<WFCMessage.CreateGroupReque
return ErrorCode.ERROR_CODE_NOT_RIGHT; return ErrorCode.ERROR_CODE_NOT_RIGHT;
} }
} }
if(requestSourceType == ProtoConstants.RequestSourceType.Request_From_User) {
ErrorCode errorCode = m_messagesStore.canAddGroupMembers(fromUser, request.getGroup().getMembersList());
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
return errorCode;
}
}
WFCMessage.GroupInfo groupInfo = m_messagesStore.createGroup(fromUser, request.getGroup().getGroupInfo(), request.getGroup().getMembersList(), request.getMemberExtra(), isAdmin); WFCMessage.GroupInfo groupInfo = m_messagesStore.createGroup(fromUser, request.getGroup().getGroupInfo(), request.getGroup().getMembersList(), request.getMemberExtra(), isAdmin);
if (groupInfo != null) { if (groupInfo != null && groupInfo.getDeleted() == 0) {
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0) { if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), request.getNotifyContent()); sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), request.getNotifyContent());
} else { } else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(groupInfo.getTargetId(), fromUser, groupInfo.getName(), "").getCreateGroupNotifyContent(); WFCMessage.MessageContent content = new GroupNotificationBinaryContent(groupInfo.getTargetId(), fromUser, groupInfo.getName(), "").setExtra(request.getMemberExtra()).getCreateGroupNotifyContent();
sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), content); sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), content);
} }
} }
@@ -10,7 +10,6 @@ package io.moquette.imhandler;
import cn.wildfirechat.proto.ProtoConstants; import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage; import cn.wildfirechat.proto.WFCMessage;
import com.xiaoleilu.hutool.system.UserInfo;
import io.moquette.persistence.MemorySessionStore; import io.moquette.persistence.MemorySessionStore;
import io.moquette.spi.impl.Qos1PublishHandler; import io.moquette.spi.impl.Qos1PublishHandler;
import io.moquette.spi.impl.security.TokenAuthenticator; import io.moquette.spi.impl.security.TokenAuthenticator;
@@ -43,13 +43,13 @@ public class QuitGroupHandler extends GroupHandler<WFCMessage.QuitGroupRequest>
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) { if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent()); sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
} else { } else {
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, "").getQuitGroupNotifyContent(); WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, request.getKeepMsg()>0?"1":"0", "").getQuitGroupNotifyContent();
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content); sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content);
} }
if((m_messagesStore.getVisibleQuitKickoffNotification() & 0x01) > 0) { if((m_messagesStore.getVisibleQuitKickoffNotification() & 0x01) > 0) {
Set<String> toUsers = m_messagesStore.getGroupManagers(request.getGroupId(), true); Set<String> toUsers = m_messagesStore.getGroupManagers(request.getGroupId(), true);
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, "").getQuitVisibleGroupNotifyContent(); WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, request.getKeepMsg()>0?"1":"0", "").getQuitVisibleGroupNotifyContent();
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content, toUsers); sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content, toUsers);
} }
} }
@@ -37,6 +37,7 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
private Set<Integer> mForwardExcludeMessageTypes = new HashSet<>(); private Set<Integer> mForwardExcludeMessageTypes = new HashSet<>();
private String mMentionForwardUrl = null; private String mMentionForwardUrl = null;
private int mBlacklistStrategy = 0; //黑名单中时,0失败,1吞掉。 private int mBlacklistStrategy = 0; //黑名单中时,0失败,1吞掉。
private boolean mBlacklistAllowSend2Black = true;
private boolean mNoForwardAdminMessage = false; private boolean mNoForwardAdminMessage = false;
private String mRemoteSensitiveServerUrl = null; private String mRemoteSensitiveServerUrl = null;
@@ -69,6 +70,12 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e);
} }
try {
mBlacklistAllowSend2Black = Boolean.parseBoolean(mServer.getConfig().getProperty(BrokerConstants.MESSAGE_Blacklist_Allow_Send, "true"));
} catch (Exception e) {
}
try { try {
mRemoteSensitiveServerUrl = mServer.getConfig().getProperty(BrokerConstants.SENSITIVE_Remote_Server_URL); mRemoteSensitiveServerUrl = mServer.getConfig().getProperty(BrokerConstants.SENSITIVE_Remote_Server_URL);
if(!StringUtil.isNullOrEmpty(mRemoteSensitiveServerUrl)) { if(!StringUtil.isNullOrEmpty(mRemoteSensitiveServerUrl)) {
@@ -145,7 +152,7 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
if (message.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Private) { if (message.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Private) {
if(!m_messagesStore.getBlackListExceptionTypes().contains(message.getContent().getType())) { if(!m_messagesStore.getBlackListExceptionTypes().contains(message.getContent().getType())) {
errorCode = m_messagesStore.isAllowUserMessage(message.getConversation().getTarget(), fromUser); errorCode = m_messagesStore.isAllowUserMessage(message.getConversation().getTarget(), fromUser, message.getConversation().getLine());
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) { if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
if (errorCode == ErrorCode.ERROR_CODE_IN_BLACK_LIST && mBlacklistStrategy != ProtoConstants.BlacklistStrategy.Message_Reject) { if (errorCode == ErrorCode.ERROR_CODE_IN_BLACK_LIST && mBlacklistStrategy != ProtoConstants.BlacklistStrategy.Message_Reject) {
ignoreMsg = true; ignoreMsg = true;
@@ -154,6 +161,13 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
return errorCode; return errorCode;
} }
} }
if(!mBlacklistAllowSend2Black) {
errorCode = m_messagesStore.isBlacked(fromUser, message.getConversation().getTarget());
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
return errorCode;
}
}
} }
userStatus = m_messagesStore.getUserStatus(message.getConversation().getTarget()); userStatus = m_messagesStore.getUserStatus(message.getConversation().getTarget());
@@ -12,7 +12,6 @@ import cn.wildfirechat.pojos.SystemSettingPojo;
import cn.wildfirechat.proto.ProtoConstants; import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage; import cn.wildfirechat.proto.WFCMessage;
import cn.wildfirechat.server.ThreadPoolExecutorWrapper; import cn.wildfirechat.server.ThreadPoolExecutorWrapper;
import com.google.protobuf.InvalidProtocolBufferException;
import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.MultiMap; import com.hazelcast.core.MultiMap;
import com.hazelcast.util.StringUtil; import com.hazelcast.util.StringUtil;
@@ -37,6 +36,7 @@ import java.util.function.Function;
import static cn.wildfirechat.common.IMExceptionEvent.EventType.RDBS_Exception; import static cn.wildfirechat.common.IMExceptionEvent.EventType.RDBS_Exception;
import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent; import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent;
import static io.moquette.BrokerConstants.GROUP_INFO_MARK_DELETION;
import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE; import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE;
import static cn.wildfirechat.proto.ProtoConstants.SearchUserType.*; import static cn.wildfirechat.proto.ProtoConstants.SearchUserType.*;
import static win.liyufan.im.UserSettingScope.kUserSettingPrivacySearchable; import static win.liyufan.im.UserSettingScope.kUserSettingPrivacySearchable;
@@ -46,6 +46,7 @@ public class DatabaseStore {
private final ThreadPoolExecutorWrapper mScheduler; private final ThreadPoolExecutorWrapper mScheduler;
private boolean disableRemoteMessageSearch = false; private boolean disableRemoteMessageSearch = false;
private boolean encryptMessage = false; private boolean encryptMessage = false;
private boolean keepGroupInfo = false;
public void setDisableRemoteMessageSearch(boolean disableRemoteMessageSearch) { public void setDisableRemoteMessageSearch(boolean disableRemoteMessageSearch) {
this.disableRemoteMessageSearch = disableRemoteMessageSearch; this.disableRemoteMessageSearch = disableRemoteMessageSearch;
} }
@@ -56,6 +57,11 @@ public class DatabaseStore {
public DatabaseStore(ThreadPoolExecutorWrapper scheduler) { public DatabaseStore(ThreadPoolExecutorWrapper scheduler) {
this.mScheduler = scheduler; this.mScheduler = scheduler;
try {
keepGroupInfo = Boolean.parseBoolean(Server.getServer().getConfig().getProperty(GROUP_INFO_MARK_DELETION, "false"));
} catch (Exception e) {
}
} }
TreeMap<Long, Long> reloadUserMessageMaps(String userId) { TreeMap<Long, Long> reloadUserMessageMaps(String userId) {
@@ -163,7 +169,7 @@ public class DatabaseStore {
return null; return null;
} }
List<WFCMessage.User> searchUserByNameMobile(String keyword, int searchType) { List<WFCMessage.User> searchUserByNameMobileUserId(String keyword, int searchType) {
ArrayList<WFCMessage.User> out = new ArrayList<>(); ArrayList<WFCMessage.User> out = new ArrayList<>();
Connection connection = null; Connection connection = null;
PreparedStatement statement = null; PreparedStatement statement = null;
@@ -182,26 +188,34 @@ public class DatabaseStore {
", `_extra`" + ", `_extra`" +
", `_dt`, `_type` from t_user"; ", `_dt`, `_type` from t_user";
int sqlParaCount = 1;
if(searchType == SearchUserType_Name) { if(searchType == SearchUserType_Name) {
sql += " where `_name` = ? "; sql += " where `_name` = ? ";
} else if(searchType == SearchUserType_Mobile) { } else if(searchType == SearchUserType_Mobile) {
sql += " where `_mobile` = ? "; sql += " where `_mobile` = ? ";
} else { } else if(searchType == SearchUserType_UserId) {
sql += " where `_uid` = ? ";
} else if(searchType == SearchUserType_Name_Mobile || searchType == SearchUserType_Name_Mobile_DisplayName) {
sqlParaCount = 2;
sql += " where (`_name` = ? or `_mobile` = ?) "; sql += " where (`_name` = ? or `_mobile` = ?) ";
} else {
sqlParaCount = 3;
sql += " where (`_name` = ? or `_mobile` = ? or `_uid` = ?) ";
} }
sql += " and `_type` <> 2 and `_deleted` = 0"; //can search normal user(0) and robot(1) and admin(100), can not search things sql += " and `_type` <> 2 and `_deleted` = 0"; //can search normal user(0) and robot(1) and admin(100), can not search things
if(searchType == SearchUserType_Name || searchType == SearchUserType_Mobile) { if(searchType == SearchUserType_Name || searchType == SearchUserType_Mobile || searchType == SearchUserType_UserId) {
sql += " limit 1"; sql += " limit 1";
} else { } else if(searchType == SearchUserType_Name_Mobile || searchType == SearchUserType_Name_Mobile_DisplayName) {
sql += " limit 2"; sql += " limit 2";
} else {
sql += " limit 3";
} }
statement = connection.prepareStatement(sql); statement = connection.prepareStatement(sql);
statement.setString(1, keyword); for (int i = 0; i < sqlParaCount; i++) {
if(searchType != SearchUserType_Name && searchType != SearchUserType_Mobile) { statement.setString(i+1, keyword);
statement.setString(2, keyword);
} }
rs = statement.executeQuery(); rs = statement.executeQuery();
@@ -284,7 +298,7 @@ public class DatabaseStore {
if (searchType == SearchUserType_Name) { if (searchType == SearchUserType_Name) {
filter.add(user); filter.add(user);
continue; continue;
} else if(searchType != SearchUserType_Mobile) { } else if(searchType == SearchUserType_Name_Mobile || searchType == SearchUserType_Name_Mobile_DisplayName) {
if(keyword.equals(user.getName())) { if(keyword.equals(user.getName())) {
if(!keyword.equals(user.getMobile())) { if(!keyword.equals(user.getMobile())) {
filter.add(user); filter.add(user);
@@ -294,15 +308,96 @@ public class DatabaseStore {
continue; continue;
} }
} }
} else if(searchType == SearchUserType_Name_Mobile_UserId) {
if(keyword.equals(user.getName())) {
if(keyword.equals(user.getMobile()) && keyword.equals(user.getUid())) {
if((value & ProtoConstants.DisableSearchMask.DisableSearchMobileMask) > 0 && (value & ProtoConstants.DisableSearchMask.DisableSearchUserIdMask) > 0) {
filter.add(user);
continue;
}
} else if(keyword.equals(user.getMobile())) {
if((value & ProtoConstants.DisableSearchMask.DisableSearchMobileMask) > 0) {
filter.add(user);
continue;
}
} else if(keyword.equals(user.getUid())) {
if((value & ProtoConstants.DisableSearchMask.DisableSearchUserIdMask) > 0) {
filter.add(user);
continue;
}
} else {
filter.add(user);
continue;
}
}
} }
} }
if ((value & ProtoConstants.DisableSearchMask.DisableSearchMobileMask) > 0) {
if((value & ProtoConstants.DisableSearchMask.DisableSearchMobileMask) > 0) {
if (searchType == SearchUserType_Mobile) { if (searchType == SearchUserType_Mobile) {
filter.add(user); filter.add(user);
} else if(searchType != SearchUserType_Name) { continue;
if(keyword.equals(user.getMobile()) && !keyword.equals(user.getName())) { } else if(searchType == SearchUserType_Name_Mobile || searchType == SearchUserType_Name_Mobile_DisplayName) {
filter.add(user); if(keyword.equals(user.getMobile())) {
if(!keyword.equals(user.getName())) {
filter.add(user);
continue;
} else if((value & ProtoConstants.DisableSearchMask.DisableSearchNameMask) > 0) {
filter.add(user);
continue;
}
}
} else if(searchType == SearchUserType_Name_Mobile_UserId) {
if(keyword.equals(user.getMobile())) {
if(keyword.equals(user.getName()) && keyword.equals(user.getUid())) {
if((value & ProtoConstants.DisableSearchMask.DisableSearchNameMask) > 0 && (value & ProtoConstants.DisableSearchMask.DisableSearchUserIdMask) > 0) {
filter.add(user);
continue;
}
} else if(keyword.equals(user.getName())) {
if((value & ProtoConstants.DisableSearchMask.DisableSearchNameMask) > 0) {
filter.add(user);
continue;
}
} else if(keyword.equals(user.getUid())) {
if((value & ProtoConstants.DisableSearchMask.DisableSearchUserIdMask) > 0) {
filter.add(user);
continue;
}
} else {
filter.add(user);
continue;
}
}
}
}
if((value & ProtoConstants.DisableSearchMask.DisableSearchUserIdMask) > 0) {
if (searchType == SearchUserType_UserId) {
filter.add(user);
continue;
} else if(searchType == SearchUserType_Name_Mobile_UserId) {
if(keyword.equals(user.getUid())) {
if(keyword.equals(user.getName()) && keyword.equals(user.getMobile())) {
if((value & ProtoConstants.DisableSearchMask.DisableSearchNameMask) > 0 && (value & ProtoConstants.DisableSearchMask.DisableSearchMobileMask) > 0) {
filter.add(user);
continue;
}
} else if(keyword.equals(user.getName())) {
if((value & ProtoConstants.DisableSearchMask.DisableSearchNameMask) > 0) {
filter.add(user);
continue;
}
} else if(keyword.equals(user.getMobile())) {
if((value & ProtoConstants.DisableSearchMask.DisableSearchMobileMask) > 0) {
filter.add(user);
continue;
}
} else {
filter.add(user);
continue;
}
} }
} }
} }
@@ -324,7 +419,7 @@ public class DatabaseStore {
connection = DBUtil.getConnection(); connection = DBUtil.getConnection();
String sql = "select u._uid, u._name, u._display_name, u._portrait, u._mobile, u._gender, u._email, u._address, u._company, u._social, u._extra, u._dt, u._type " + String sql = "select u._uid, u._name, u._display_name, u._portrait, u._mobile, u._gender, u._email, u._address, u._company, u._social, u._extra, u._dt, u._type " +
" from t_user u left join (select _uid, _value from t_user_setting where _scope = 27) s on u._uid = s._uid " + " from t_user u left join (select _uid, _value from t_user_setting where _scope = 27) s on u._uid = s._uid " +
" where u._display_name like ? and u._type <> 2 and u._deleted = 0 "; " where u._display_name like ? ESCAPE '!' and u._type <> 2 and u._deleted = 0 ";
if(nameOrIdMatched.size() == 1) { if(nameOrIdMatched.size() == 1) {
sql += " and u._uid <> ? and u._name <> ?"; sql += " and u._uid <> ? and u._name <> ?";
} else if(nameOrIdMatched.size() == 2) { } else if(nameOrIdMatched.size() == 2) {
@@ -342,6 +437,12 @@ public class DatabaseStore {
sql += " offset " + (page * 20 - nameOrIdMatched.size()); sql += " offset " + (page * 20 - nameOrIdMatched.size());
} }
keyword = keyword
.replace("!", "!!")
.replace("%", "!%")
.replace("_", "!_")
.replace("[", "![");
statement = connection.prepareStatement(sql); statement = connection.prepareStatement(sql);
statement.setString(1, "%" + keyword + "%"); statement.setString(1, "%" + keyword + "%");
if(nameOrIdMatched.size() == 1) { if(nameOrIdMatched.size() == 1) {
@@ -423,13 +524,13 @@ public class DatabaseStore {
} }
List<WFCMessage.User> searchUserFromDB(String keyword, int searchType, int page) { List<WFCMessage.User> searchUserFromDB(String keyword, int searchType, int page) {
List<WFCMessage.User> nameOrIdMatched = searchUserByNameMobile(keyword, searchType); List<WFCMessage.User> nameOrIdMatched = searchUserByNameMobileUserId(keyword, searchType);
List<WFCMessage.User> out = new ArrayList<>(); List<WFCMessage.User> out = new ArrayList<>();
if(page == 0) { if(page == 0) {
out.addAll(nameOrIdMatched); out.addAll(nameOrIdMatched);
} }
if(searchType == SearchUserType_General) { if(searchType == SearchUserType_General || searchType == SearchUserType_Name_Mobile_DisplayName) {
List<WFCMessage.User> general = searchUserByDisplayName(keyword, page, nameOrIdMatched); List<WFCMessage.User> general = searchUserByDisplayName(keyword, page, nameOrIdMatched);
general.removeAll(nameOrIdMatched); general.removeAll(nameOrIdMatched);
out.addAll(general); out.addAll(general);
@@ -1035,7 +1136,16 @@ public class DatabaseStore {
} }
if (!expired) { if (!expired) {
messages.add(message); boolean duplicated = false;
for (WFCMessage.Message msg : messages) {
if(message.getMessageId() == msg.getMessageId()) {
duplicated = true;
break;
}
}
if(!duplicated) {
messages.add(message);
}
} }
} }
@@ -1331,7 +1441,8 @@ public class DatabaseStore {
", `_join_type`" + ", `_join_type`" +
", `_private_chat`" + ", `_private_chat`" +
", `_searchable`" + ", `_searchable`" +
", `_member_dt`) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + ", `_deleted`" +
", `_member_dt`) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" +
" ON DUPLICATE KEY UPDATE " + " ON DUPLICATE KEY UPDATE " +
"`_name` = ?," + "`_name` = ?," +
"`_portrait` = ?," + "`_portrait` = ?," +
@@ -1342,8 +1453,9 @@ public class DatabaseStore {
"`_mute` = ?" + "`_mute` = ?" +
", `_join_type` = ?" + ", `_join_type` = ?" +
", `_private_chat` = ?" + ", `_private_chat` = ?" +
", `_searchable` = ?, " + ", `_searchable` = ?" +
"`_member_dt` = ?"; ", `_deleted` = ?" +
", `_member_dt` = ?";
statement = connection.prepareStatement(sql); statement = connection.prepareStatement(sql);
@@ -1361,6 +1473,7 @@ public class DatabaseStore {
statement.setInt(index++, groupInfo.getJoinType()); statement.setInt(index++, groupInfo.getJoinType());
statement.setInt(index++, groupInfo.getPrivateChat()); statement.setInt(index++, groupInfo.getPrivateChat());
statement.setInt(index++, groupInfo.getSearchable()); statement.setInt(index++, groupInfo.getSearchable());
statement.setInt(index++, groupInfo.getDeleted());
statement.setLong(index++, groupInfo.getMemberUpdateDt() == 0 ? System.currentTimeMillis() : groupInfo.getUpdateDt()); statement.setLong(index++, groupInfo.getMemberUpdateDt() == 0 ? System.currentTimeMillis() : groupInfo.getUpdateDt());
statement.setString(index++, groupInfo.getName()); statement.setString(index++, groupInfo.getName());
@@ -1373,6 +1486,7 @@ public class DatabaseStore {
statement.setInt(index++, groupInfo.getJoinType()); statement.setInt(index++, groupInfo.getJoinType());
statement.setInt(index++, groupInfo.getPrivateChat()); statement.setInt(index++, groupInfo.getPrivateChat());
statement.setInt(index++, groupInfo.getSearchable()); statement.setInt(index++, groupInfo.getSearchable());
statement.setInt(index++, groupInfo.getDeleted());
statement.setLong(index++, groupInfo.getMemberUpdateDt() == 0 ? System.currentTimeMillis() : groupInfo.getUpdateDt()); statement.setLong(index++, groupInfo.getMemberUpdateDt() == 0 ? System.currentTimeMillis() : groupInfo.getUpdateDt());
int count = statement.executeUpdate(); int count = statement.executeUpdate();
LOG.info("Update rows {}", count); LOG.info("Update rows {}", count);
@@ -1704,10 +1818,12 @@ public class DatabaseStore {
try { try {
connection = DBUtil.getConnection(); connection = DBUtil.getConnection();
String sql; 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 || platform == ProtoConstants.Platform.Platform_HarmonyPC) {
sql = "update t_user_session set `_deleted` = ?, `_token` = ?, `_voip_token` = ?, `_dt` = ? where `_uid`=? and (`_platform` = ? or `_platform` = ? or `_platform` = ? or `_platform` = ?) and `_cid` <> ? and `_deleted` = 0";
} else if(platform == ProtoConstants.Platform.Platform_iOS || platform == ProtoConstants.Platform.Platform_Android || platform == ProtoConstants.Platform.Platform_Harmony) {
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_iPad || platform == ProtoConstants.Platform.Platform_APad || platform == ProtoConstants.Platform.Platform_HarmonyPad) {
sql = "update t_user_session set `_deleted` = ?, `_token` = ?, `_voip_token` = ?, `_dt` = ? where `_uid`=? and (`_platform` = ? or `_platform` = ? or `_platform` = ?) and `_cid` <> ? and `_deleted` = 0"; 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";
} else { } else {
sql = "update t_user_session set `_deleted` = ?, `_token` = ?, `_voip_token` = ?, `_dt` = ? where `_uid`=? and `_platform` = ? and `_cid` <> ? and `_deleted` = 0"; sql = "update t_user_session set `_deleted` = ?, `_token` = ?, `_voip_token` = ?, `_dt` = ? where `_uid`=? and `_platform` = ? and `_cid` <> ? and `_deleted` = 0";
} }
@@ -1722,13 +1838,19 @@ public class DatabaseStore {
statement.setString(index++, uid); 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 || platform == ProtoConstants.Platform.Platform_HarmonyPC) {
statement.setInt(index++, ProtoConstants.Platform.Platform_Windows); statement.setInt(index++, ProtoConstants.Platform.Platform_Windows);
statement.setInt(index++, ProtoConstants.Platform.Platform_OSX); 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_HarmonyPC);
} else if(platform == ProtoConstants.Platform.Platform_iOS || platform == ProtoConstants.Platform.Platform_Android || platform == ProtoConstants.Platform.Platform_Harmony) {
statement.setInt(index++, ProtoConstants.Platform.Platform_iOS); statement.setInt(index++, ProtoConstants.Platform.Platform_iOS);
statement.setInt(index++, ProtoConstants.Platform.Platform_Android); statement.setInt(index++, ProtoConstants.Platform.Platform_Android);
statement.setInt(index++, ProtoConstants.Platform.Platform_Harmony);
} else if(platform == ProtoConstants.Platform.Platform_iPad || platform == ProtoConstants.Platform.Platform_APad || platform == ProtoConstants.Platform.Platform_HarmonyPad) {
statement.setInt(index++, ProtoConstants.Platform.Platform_iPad);
statement.setInt(index++, ProtoConstants.Platform.Platform_APad);
statement.setInt(index++, ProtoConstants.Platform.Platform_HarmonyPad);
} else { } else {
statement.setInt(index++, platform); statement.setInt(index++, platform);
} }
@@ -1845,6 +1967,45 @@ public class DatabaseStore {
return null; return null;
} }
Set<String> getUserGroupIds(String userId, List<Integer> memberTypes) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet rs = null;
try {
connection = DBUtil.getConnection();
String sql = "select _gid from t_group_member where _mid = ? ";
if(!memberTypes.isEmpty()) {
sql += " and _type in (";
for (int i = 0; i < memberTypes.size(); i++) {
if(i > 0) {
sql += ",";
}
sql += memberTypes.get(i);
}
sql += ")";
}
statement = connection.prepareStatement(sql);
statement.setString(1, userId);
rs = statement.executeQuery();
Set<String> out = new HashSet<>();
while (rs.next()) {
String uid = rs.getString(1);
out.add(uid);
}
return out;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
return null;
}
Set<String> getCommonGroupIds(String userId1, String userId2) { Set<String> getCommonGroupIds(String userId1, String userId2) {
Connection connection = null; Connection connection = null;
PreparedStatement statement = null; PreparedStatement statement = null;
@@ -2042,6 +2203,7 @@ public class DatabaseStore {
", `_join_type`" + ", `_join_type`" +
", `_private_chat`" + ", `_private_chat`" +
", `_searchable`" + ", `_searchable`" +
", _deleted" +
" from t_group where `_gid` = ?"; " from t_group where `_gid` = ?";
statement = connection.prepareStatement(sql); statement = connection.prepareStatement(sql);
@@ -2098,6 +2260,9 @@ public class DatabaseStore {
intValue = rs.getInt(index++); intValue = rs.getInt(index++);
builder.setSearchable(intValue); builder.setSearchable(intValue);
intValue = rs.getInt(index++);
builder.setDeleted(intValue);
return builder.build(); return builder.build();
} }
} catch (SQLException e) { } catch (SQLException e) {
@@ -2776,6 +2941,99 @@ public class DatabaseStore {
return null; return null;
} }
List<WFCMessage.User> getUserInfosByEmail(String email) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet rs = null;
List<WFCMessage.User> outList = new ArrayList<>();
try {
connection = DBUtil.getConnection();
String sql = "select `_uid`, `_name`" +
", `_display_name`" +
", `_portrait`" +
", `_mobile`" +
", `_gender`" +
", `_email`" +
", `_address`" +
", `_company`" +
", `_social`" +
", `_extra`" +
", `_type`" +
", `_deleted`" +
", `_dt` from t_user where `_deleted` = 0 and `_email` = ?";
statement = connection.prepareStatement(sql);
statement.setString(1, email);
rs = statement.executeQuery();
while (rs.next()) {
WFCMessage.User.Builder builder = WFCMessage.User.newBuilder();
int index = 1;
String value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setUid(value);
value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setName(value);
value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setDisplayName(value);
value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setPortrait(value);
value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setMobile(value);
int gender = rs.getInt(index++);
builder.setGender(gender);
value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setEmail(value);
value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setAddress(value);
value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setCompany(value);
value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setSocial(value);
value = rs.getString(index++);
value = (value == null ? "" : value);
builder.setExtra(value);
int type = rs.getInt(index++);
builder.setType(type);
int deleted = rs.getInt(index++);
builder.setDeleted(deleted);
long longValue = rs.getLong(index++);
if(longValue <= 0)
longValue = 1;
builder.setUpdateDt(longValue);
outList.add(builder.build());
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
return outList;
}
List<WFCMessage.User> getAllUsers(int count, int offset) { List<WFCMessage.User> getAllUsers(int count, int offset) {
Connection connection = null; Connection connection = null;
PreparedStatement statement = null; PreparedStatement statement = null;
@@ -2873,17 +3131,20 @@ public class DatabaseStore {
return outList; return outList;
} }
Set<String> getAllEnds() { Set<String> getAllEnds(boolean fromUserTable) {
Connection connection = null; Connection connection = null;
PreparedStatement statement = null; PreparedStatement statement = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
connection = DBUtil.getConnection(); connection = DBUtil.getConnection();
String sql = "select distinct(`_uid`) from t_user_session where `_deleted` = 0"; String sql;
if(fromUserTable) {
sql = "select distinct(`_uid`) from t_user_session";
} else {
sql = "select distinct(`_uid`) from t_user where `_deleted` = 0 and `_type` <> 1 and `_type` <> 2";
}
statement = connection.prepareStatement(sql); statement = connection.prepareStatement(sql);
rs = statement.executeQuery(); rs = statement.executeQuery();
Set<String> out = new HashSet<>(); Set<String> out = new HashSet<>();
while (rs.next()) { while (rs.next()) {
@@ -3173,8 +3434,12 @@ public class DatabaseStore {
PreparedStatement statement = null; PreparedStatement statement = null;
try { try {
connection = DBUtil.getConnection(); connection = DBUtil.getConnection();
String sql = "delete from t_group where _gid = ?"; String sql;
if(keepGroupInfo) {
sql = "update t_group set _deleted = 1, _dt = _dt+1, _member_count = 0, _member_dt = _member_dt+1 where _gid = ?";
} else {
sql = "delete from t_group where _gid = ?";
}
statement = connection.prepareStatement(sql); statement = connection.prepareStatement(sql);
int index = 1; int index = 1;
@@ -3501,12 +3766,16 @@ public class DatabaseStore {
", `_extra`" + ", `_extra`" +
", `_dt` from t_channel"; ", `_dt` from t_channel";
if (buzzy) { if (buzzy) {
sql += " where `_name` like ?"; sql += " where `_name` like ? ESCAPE '!' ";
} else { } else {
sql += " where `_name` = ?"; sql += " where `_name` = ?";
} }
sql += " and _status = 0"; sql += " and _status <> 64";
sql += " and _status <> 16";
sql += " and _status <> 17";
sql += " and _status <> 24";
sql += " and _status <> 25";
sql += " limit 20"; sql += " limit 20";
@@ -3515,6 +3784,12 @@ public class DatabaseStore {
sql += " offset " + page * 20; sql += " offset " + page * 20;
} }
keyword = keyword
.replace("!", "!!")
.replace("%", "!%")
.replace("_", "!_")
.replace("[", "![");
statement = connection.prepareStatement(sql); statement = connection.prepareStatement(sql);
int index = 1; int index = 1;
if (buzzy) { if (buzzy) {
@@ -23,6 +23,8 @@ import com.google.gson.Gson;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
import com.hazelcast.core.*; import com.hazelcast.core.*;
import com.hazelcast.util.StringUtil; import com.hazelcast.util.StringUtil;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.action.Action;
import com.xiaoleilu.loServer.action.admin.AdminAction; import com.xiaoleilu.loServer.action.admin.AdminAction;
import com.xiaoleilu.loServer.model.FriendData; import com.xiaoleilu.loServer.model.FriendData;
import cn.wildfirechat.common.ErrorCode; import cn.wildfirechat.common.ErrorCode;
@@ -48,6 +50,7 @@ import java.net.URL;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReadWriteLock;
@@ -72,6 +75,7 @@ import static io.moquette.BrokerConstants.*;
import static io.moquette.server.Constants.MAX_CHATROOM_MESSAGE_QUEUE; import static io.moquette.server.Constants.MAX_CHATROOM_MESSAGE_QUEUE;
import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE; import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE;
import static cn.wildfirechat.pojos.MyInfoType.*; import static cn.wildfirechat.pojos.MyInfoType.*;
import static win.liyufan.im.UserSettingScope.kUserSettingAddFriendStrategy;
import static win.liyufan.im.UserSettingScope.kUserSettingPCOnline; import static win.liyufan.im.UserSettingScope.kUserSettingPCOnline;
public class MemoryMessagesStore implements IMessagesStore { public class MemoryMessagesStore implements IMessagesStore {
@@ -137,18 +141,34 @@ public class MemoryMessagesStore implements IMessagesStore {
private ConcurrentHashMap<String, Boolean> userPushHiddenDetail = new ConcurrentHashMap<>(); private ConcurrentHashMap<String, Boolean> userPushHiddenDetail = new ConcurrentHashMap<>();
private ConcurrentHashMap<String, Boolean> userConvSlientMap = new ConcurrentHashMap<>(); private ConcurrentHashMap<String, Boolean> userConvSlientMap = new ConcurrentHashMap<>();
private LinkedHashMap<String, Long> repeatFriendRequest = new LinkedHashMap<String, Long>() {
@Override
protected boolean removeEldestEntry(Map.Entry<String, Long> eldest) {
return System.currentTimeMillis() - eldest.getValue() > 5 * 60 * 1000;
}
};
private boolean mDisableSearch = false; private boolean mDisableSearch = false;
private boolean mDisableNicknameSearch = false; private boolean mDisableNicknameSearch = false;
private boolean mDisableUserIdSearch = false;
private boolean mDisableFriendRequest = false; private boolean mDisableFriendRequest = false;
private long mFriendRequestDuration = 7 * 24 * 60 * 60 * 1000; private long mFriendRequestDuration = 7 * 24 * 60 * 60 * 1000;
private long mFriendRejectDuration = 30 * 24 * 60 * 60 * 1000; private long mFriendRejectDuration = 30 * 24 * 60 * 60 * 1000;
private long mFriendRequestExpiration = 7 * 24 * 60 * 60 * 1000; private long mFriendRequestExpiration = 7 * 24 * 60 * 60 * 1000;
private RateLimiter mFriendRateLimiter;
private boolean mFriendRobotAutoAccept = true; private boolean mFriendRobotAutoAccept = true;
private long mPushExpiredTimes = 604800000L;
private Set<Integer> mForcePushTypes = new HashSet<>();
private boolean mMultiPlatformNotification = false; private boolean mMultiPlatformNotification = false;
private boolean mMobileDefaultSilentWhenPCOnline = true; private boolean mMobileDefaultSilentWhenPCOnline = true;
private boolean mDisableStrangerChat = false; private boolean mDisableStrangerChat = false;
private Set<String> mAllowStrangerChatSet = new HashSet<>(); private Set<String> mAllowStrangerChatSet = new HashSet<>();
private Set<Integer> mAllowStrangerLineSet = new HashSet<>();
private boolean mDisableStrangerAddGroup = false;
private boolean mIDUseUUID = true;
private Set<String> mClientSignatureSet = new HashSet<>(); private Set<String> mClientSignatureSet = new HashSet<>();
private boolean mRejectEmptySignature = true; private boolean mRejectEmptySignature = true;
@@ -156,6 +176,7 @@ public class MemoryMessagesStore implements IMessagesStore {
private long mChatroomParticipantIdleTime = 900000; private long mChatroomParticipantIdleTime = 900000;
private boolean mChatroomRejoinWhenActive = true; private boolean mChatroomRejoinWhenActive = true;
private boolean mChatroomCreateWhenNotExist = true; private boolean mChatroomCreateWhenNotExist = true;
private boolean mChatroomKickoffOtherPlatform = true;
private List<Integer> mForbiddenClientSendTypes = new ArrayList<>(); private List<Integer> mForbiddenClientSendTypes = new ArrayList<>();
private List<Integer> mBlackListExceptionTypes = new ArrayList<>(); private List<Integer> mBlackListExceptionTypes = new ArrayList<>();
@@ -171,6 +192,8 @@ public class MemoryMessagesStore implements IMessagesStore {
private String mChannelInfoUpdateCallback; private String mChannelInfoUpdateCallback;
private String mChatroomInfoUpdateCallback; private String mChatroomInfoUpdateCallback;
private String mChatroomMemberUpdateCallback; private String mChatroomMemberUpdateCallback;
private boolean mGroupAllowOwnerRecallSelfMsg = false;
private boolean mGroupAllowManagerRecallSelfMsg = false;
private boolean mGroupAllowClientCustomOperationNotification; private boolean mGroupAllowClientCustomOperationNotification;
private boolean mGroupAllowRobotCustomOperationNotification; private boolean mGroupAllowRobotCustomOperationNotification;
private int mGroupVisibleQuitKickoffNotification; private int mGroupVisibleQuitKickoffNotification;
@@ -179,9 +202,12 @@ public class MemoryMessagesStore implements IMessagesStore {
private boolean keepDisplayNameWhenDestroyUser = true; private boolean keepDisplayNameWhenDestroyUser = true;
private String mRecallForwardUrl = null; private String mRecallForwardUrl = null;
private boolean mBroadcastTargetFromUserTable = false;
private boolean mForwardMessageWithClientInfo = false; private boolean mForwardMessageWithClientInfo = false;
private boolean mRobotCallbackWithClientInfo = false; private boolean mRobotCallbackWithClientInfo = false;
private boolean mChannelCallbackWithClientInfo = false; private boolean mChannelCallbackWithClientInfo = false;
private boolean mChannelNewCallbackFeature = true;
private Set<Integer> mUserHideProperties = new HashSet<>(); private Set<Integer> mUserHideProperties = new HashSet<>();
@@ -240,6 +266,32 @@ public class MemoryMessagesStore implements IMessagesStore {
e.printStackTrace(); e.printStackTrace();
} }
try {
String allowStrangerList = m_Server.getConfig().getProperty(BrokerConstants.MESSAGE_Allow_Stranger_Line);
if(!StringUtil.isNullOrEmptyAfterTrim(allowStrangerList)) {
allowStrangerList = allowStrangerList.replace(",", ",");
for (String s : allowStrangerList.split(",")) {
mAllowStrangerLineSet.add(Integer.parseInt(s.trim()));
}
}
} catch (Exception e) {
e.printStackTrace();
}
try {
String forcePushTypes = m_Server.getConfig().getProperty(BrokerConstants.MESSAGE_Force_Push_Types);
if(!StringUtil.isNullOrEmptyAfterTrim(forcePushTypes)) {
forcePushTypes = forcePushTypes.replace(",", ",");
for (String s : forcePushTypes.split(",")) {
int type = Integer.parseInt(s.trim());
if(type > 0) {
mForcePushTypes.add(type);
}
}
}
} catch (Exception e) {
}
try { try {
mMultiPlatformNotification = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.SERVER_MULTI_PLATFROM_NOTIFICATION, "false")); mMultiPlatformNotification = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.SERVER_MULTI_PLATFROM_NOTIFICATION, "false"));
} catch (Exception e) { } catch (Exception e) {
@@ -268,6 +320,12 @@ public class MemoryMessagesStore implements IMessagesStore {
Utility.printExecption(LOG, e); Utility.printExecption(LOG, e);
printMissConfigLog(FRIEND_Disable_NickName_Search, mDisableNicknameSearch + ""); printMissConfigLog(FRIEND_Disable_NickName_Search, mDisableNicknameSearch + "");
} }
try {
mDisableUserIdSearch = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.FRIEND_Disable_UserId_Search, "true"));
} catch (Exception e) {
}
try { try {
mDisableFriendRequest = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.FRIEND_Disable_Friend_Request)); mDisableFriendRequest = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.FRIEND_Disable_Friend_Request));
} catch (Exception e) { } catch (Exception e) {
@@ -300,12 +358,25 @@ public class MemoryMessagesStore implements IMessagesStore {
printMissConfigLog(FRIEND_Request_Expiration_Duration, mFriendRequestExpiration + ""); printMissConfigLog(FRIEND_Request_Expiration_Duration, mFriendRequestExpiration + "");
} }
try {
int friendRequestRateLimit = Integer.parseInt(m_Server.getConfig().getProperty(FRIEND_Request_Rate_Limit, "0"));
if(friendRequestRateLimit > 0) {
mFriendRateLimiter = new RateLimiter(86400, friendRequestRateLimit);
}
} catch (Exception e) {
}
try { try {
mFriendRobotAutoAccept = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.FRIEND_Request_Robot_Auto_Accept, "true")); mFriendRobotAutoAccept = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.FRIEND_Request_Robot_Auto_Accept, "true"));
} catch (Exception e) { } catch (Exception e) {
} }
try {
mPushExpiredTimes = Long.parseLong(m_Server.getConfig().getProperty(BrokerConstants.MESSAGE_Push_Expired_Days, "7")) * 86400000L;
if(mPushExpiredTimes == 0) mPushExpiredTimes = Long.MAX_VALUE;
} catch (Exception e) {
}
try { try {
mChatroomRejoinWhenActive = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.CHATROOM_Rejoin_When_Active)); mChatroomRejoinWhenActive = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.CHATROOM_Rejoin_When_Active));
} catch (Exception e) { } catch (Exception e) {
@@ -322,6 +393,12 @@ public class MemoryMessagesStore implements IMessagesStore {
printMissConfigLog(CHATROOM_Create_When_Not_Exist, mChatroomCreateWhenNotExist + ""); printMissConfigLog(CHATROOM_Create_When_Not_Exist, mChatroomCreateWhenNotExist + "");
} }
try {
mChatroomKickoffOtherPlatform = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.CHATROOM_Kickoff_Other_Platform, "true"));
} catch (Exception e) {
}
try { try {
mChatroomParticipantIdleTime = Long.parseLong(m_Server.getConfig().getProperty(CHATROOM_Participant_Idle_Time, "900000")); mChatroomParticipantIdleTime = Long.parseLong(m_Server.getConfig().getProperty(CHATROOM_Participant_Idle_Time, "900000"));
} catch (Exception e) { } catch (Exception e) {
@@ -453,6 +530,17 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
try {
mGroupAllowOwnerRecallSelfMsg = Boolean.parseBoolean(server.getConfig().getProperty(GROUP_Allow_Owner_Recall_Self_Msg, "true"));
} catch (Exception e) {
}
try {
mGroupAllowManagerRecallSelfMsg = Boolean.parseBoolean(server.getConfig().getProperty(GROUP_Allow_Manager_Recall_Self_Msg, "false"));
} catch (Exception e) {
}
try { try {
mGroupAllowClientCustomOperationNotification = Boolean.parseBoolean(server.getConfig().getProperty(GROUP_Allow_Client_Custom_Operation_Notification)); mGroupAllowClientCustomOperationNotification = Boolean.parseBoolean(server.getConfig().getProperty(GROUP_Allow_Client_Custom_Operation_Notification));
} catch (Exception e) { } catch (Exception e) {
@@ -471,6 +559,11 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
try {
mDisableStrangerAddGroup = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.GROUP_Disable_Stranger_Invite, "false"));
} catch (Exception e) {
}
try { try {
String s = server.getConfig().getProperty(GROUP_Forbidden_Client_Operation, null); String s = server.getConfig().getProperty(GROUP_Forbidden_Client_Operation, null);
if(!StringUtil.isNullOrEmptyAfterTrim(s)) { if(!StringUtil.isNullOrEmptyAfterTrim(s)) {
@@ -518,6 +611,13 @@ public class MemoryMessagesStore implements IMessagesStore {
} catch (Exception e) { } catch (Exception e) {
} }
try {
mBroadcastTargetFromUserTable = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.BROADCAST_Target_From_User_Table, "false"));
} catch (Exception e) {
}
try { try {
mRobotCallbackWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.ROBOT_Callback_With_Client_Info, "false")); mRobotCallbackWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.ROBOT_Callback_With_Client_Info, "false"));
} catch (Exception e) { } catch (Exception e) {
@@ -526,13 +626,22 @@ public class MemoryMessagesStore implements IMessagesStore {
try { try {
mChannelCallbackWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_Callback_With_Client_Info, "false")); mChannelCallbackWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_Callback_With_Client_Info, "false"));
} catch (Exception e) { } catch (Exception e) {
} }
try {
mChannelNewCallbackFeature = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_New_Callback_Feature, "true"));
} catch (Exception e) {
}
try { try {
mRecallForwardUrl = server.getConfig().getProperty(BrokerConstants.MESSAGE_RecallMsg_Forward_Url); mRecallForwardUrl = server.getConfig().getProperty(BrokerConstants.MESSAGE_RecallMsg_Forward_Url);
} catch (Exception e) { } catch (Exception e) {
} }
try {
mIDUseUUID = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.ID_USE_UUID, "false"));
} catch (Exception e) {
}
} }
private void printMissConfigLog(String config, String defaultValue) { private void printMissConfigLog(String config, String defaultValue) {
@@ -637,7 +746,7 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
pullType = ProtoConstants.PullType.Pull_Normal; pullType = ProtoConstants.PullType.Pull_Normal;
} else if (type == ProtoConstants.ConversationType.ConversationType_ChatRoom) { } else if (type == ProtoConstants.ConversationType.ConversationType_ChatRoom) {
boolean isDirect = !StringUtil.isNullOrEmpty(message.getToUser()); boolean isDirect = !StringUtil.isNullOrEmpty(message.getToUser()) || !message.getToList().isEmpty();
Collection<UserClientEntry> entries = getChatroomMembers(message.getConversation().getTarget()); Collection<UserClientEntry> entries = getChatroomMembers(message.getConversation().getTarget());
for (UserClientEntry entry : entries) { for (UserClientEntry entry : entries) {
if (isDirect) { if (isDirect) {
@@ -645,6 +754,9 @@ public class MemoryMessagesStore implements IMessagesStore {
notifyReceivers.add(message.getToUser()); notifyReceivers.add(message.getToUser());
break; break;
} }
if (message.getToList().contains(entry.userId)) {
notifyReceivers.add(entry.userId);
}
} else { } else {
notifyReceivers.add(entry.userId); notifyReceivers.add(entry.userId);
} }
@@ -656,7 +768,7 @@ public class MemoryMessagesStore implements IMessagesStore {
if (channelInfo != null) { if (channelInfo != null) {
if (channelInfo.getOwner().equals(fromUser)) { if (channelInfo.getOwner().equals(fromUser)) {
if(requestSourceType == ProtoConstants.RequestSourceType.Request_From_Channel if(requestSourceType == ProtoConstants.RequestSourceType.Request_From_Channel
&& channelInfo.getAutomatic() != 0) { && channelInfo.getAutomatic() != 0 && !isChannelNewCallbackFeature()) {
LOG.info("Channel api message not send to the owner when automatic"); LOG.info("Channel api message not send to the owner when automatic");
} else { } else {
notifyReceivers.add(fromUser); notifyReceivers.add(fromUser);
@@ -686,7 +798,7 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
} else { } else {
notifyReceivers.add(fromUser); notifyReceivers.add(fromUser);
if (channelInfo.getAutomatic() == 0) { if (channelInfo.getAutomatic() == 0 || isChannelNewCallbackFeature()) {
notifyReceivers.add(channelInfo.getOwner()); notifyReceivers.add(channelInfo.getOwner());
} else { } else {
LOG.info("Channel api message not send to the owner when automatic"); LOG.info("Channel api message not send to the owner when automatic");
@@ -706,7 +818,7 @@ public class MemoryMessagesStore implements IMessagesStore {
@Override @Override
public Set<String> getAllEnds() { public Set<String> getAllEnds() {
return databaseStore.getAllEnds(); return databaseStore.getAllEnds(mBroadcastTargetFromUserTable);
} }
@Override @Override
public WFCMessage.PullMessageResult fetchMessage(String user, String exceptClientId, long fromMessageId, int pullType) { public WFCMessage.PullMessageResult fetchMessage(String user, String exceptClientId, long fromMessageId, int pullType) {
@@ -898,7 +1010,29 @@ public class MemoryMessagesStore implements IMessagesStore {
Collection<UserClientEntry> members = chatroomMembers.get(chatroomId); Collection<UserClientEntry> members = chatroomMembers.get(chatroomId);
return members; return members;
} }
//Todo chatroom
@Override
public OutputUserChatroom getUserChatroom(String userId) {
String chatroomId = (String) m_Server.getHazelcastInstance().getMap(USER_CHATROOM).get(userId);
if(chatroomId != null) {
MultiMap<String, UserClientEntry> chatroomMembers = m_Server.getHazelcastInstance().getMultiMap(CHATROOM_MEMBER_IDS);
for (UserClientEntry userClientEntry : chatroomMembers.get(chatroomId)) {
if(userClientEntry.userId.equals(userId)) {
OutputUserChatroom outputUserChatroom = new OutputUserChatroom();
outputUserChatroom.userId = userId;
outputUserChatroom.chatroomId = chatroomId;
outputUserChatroom.clientId = userClientEntry.clientId;
MemorySessionStore.Session session = m_Server.getStore().sessionsStore().getSession(userClientEntry.clientId);
if(session != null) {
outputUserChatroom.platform = session.getPlatform();
}
return outputUserChatroom;
}
}
}
return null;
}
@Override @Override
public WFCMessage.PullMessageResult fetchChatroomMessage(String fromUser, String chatroomId, String exceptClientId, long fromMessageId) { public WFCMessage.PullMessageResult fetchChatroomMessage(String fromUser, String chatroomId, String exceptClientId, long fromMessageId) {
WFCMessage.PullMessageResult.Builder builder = WFCMessage.PullMessageResult.newBuilder(); WFCMessage.PullMessageResult.Builder builder = WFCMessage.PullMessageResult.newBuilder();
@@ -1121,6 +1255,85 @@ public class MemoryMessagesStore implements IMessagesStore {
return messageSeq; return messageSeq;
} }
@Override
public ErrorCode canAddGroupMembers(String fromUser, List<WFCMessage.GroupMember> memberList) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
MultiMap<String, FriendData> friendsMap = hzInstance.getMultiMap(USER_FRIENDS);
IMap<String, WFCMessage.User> mUserMap = hzInstance.getMap(USERS);
WFCMessage.User operator = mUserMap.get(fromUser);
if(operator != null && operator.getType() > 1) {
return ErrorCode.ERROR_CODE_SUCCESS;
}
if (mDisableStrangerAddGroup) {
for (WFCMessage.GroupMember groupMember : memberList) {
String targetUser = groupMember.getMemberId();
if(fromUser.equals(targetUser)) {
continue;
}
Collection<FriendData> friendDatas = friendsMap.get(targetUser);
if (friendDatas == null || friendDatas.size() == 0) {
friendDatas = loadFriend(friendsMap, targetUser);
}
boolean allow = false;
for (FriendData friendData : friendDatas) {
if (friendData.getFriendUid().equals(fromUser)) {
if (friendData.getBlacked() == 1) {
return ErrorCode.ERROR_CODE_IN_BLACK_LIST;
} else {
if (friendData.getState() == 0) {
allow = true;
}
break;
}
}
}
if(allow) {
continue;
}
//在禁止私聊时,是否是允许私聊的用户id
if(mAllowStrangerChatSet.contains(targetUser) || mAllowStrangerChatSet.contains(fromUser)) {
continue;
}
//在禁止私聊时,允许机器人,物联网设备及管理员进行私聊。
WFCMessage.User target = mUserMap.get(targetUser);
if (target != null && target.getType() != ProtoConstants.UserType.UserType_Normal) {
continue;
}
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
} else {
for (WFCMessage.GroupMember groupMember : memberList) {
String targetUser = groupMember.getMemberId();
if(fromUser.equals(targetUser)) {
continue;
}
Collection<FriendData> friendDatas = friendsMap.get(targetUser);
if (friendDatas == null || friendDatas.size() == 0) {
friendDatas = loadFriend(friendsMap, targetUser);
}
for (FriendData friendData : friendDatas) {
if (friendData.getFriendUid().equals(fromUser)) {
if (friendData.getBlacked() == 1) {
return ErrorCode.ERROR_CODE_IN_BLACK_LIST;
} else {
break;
}
}
}
}
}
return ErrorCode.ERROR_CODE_SUCCESS;
}
@Override @Override
public WFCMessage.GroupInfo createGroup(String fromUser, WFCMessage.GroupInfo groupInfo, List<WFCMessage.GroupMember> memberList, String memberExtra, boolean isAdmin) { public WFCMessage.GroupInfo createGroup(String fromUser, WFCMessage.GroupInfo groupInfo, List<WFCMessage.GroupMember> memberList, String memberExtra, boolean isAdmin) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance(); HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
@@ -1196,17 +1409,35 @@ public class MemoryMessagesStore implements IMessagesStore {
mIMap.set(groupId, groupInfo); mIMap.set(groupId, groupInfo);
databaseStore.persistGroupMember(groupId, updatedMemberList, false); databaseStore.persistGroupMember(groupId, updatedMemberList, false);
callbackGroupEvent(fromUser, groupInfo.getTargetId(), ProtoConstants.GroupUpdateEventType.Group_Event_Create); callbackGroupEvent(fromUser, groupInfo.getTargetId(), ProtoConstants.GroupUpdateEventType.Group_Event_Create, groupInfo);
return groupInfo; return groupInfo;
} }
private void callbackGroupEvent(String operatorId, String groupId, int type) { private void callbackGroupEvent(String operatorId, String groupId, int type, WFCMessage.GroupInfo groupInfo) {
if (!StringUtil.isNullOrEmpty(mGroupInfoUpdateCallback)) { if (!StringUtil.isNullOrEmpty(mGroupInfoUpdateCallback)) {
GroupUpdateEvent event = new GroupUpdateEvent(); GroupUpdateEvent event = new GroupUpdateEvent();
event.operatorId = operatorId; event.operatorId = operatorId;
event.groupId = groupId; event.groupId = groupId;
event.type = type; event.type = type;
PojoGroupInfo pojoGroupInfo = new PojoGroupInfo();
event.groupInfo = pojoGroupInfo;
if (groupInfo != null && groupInfo.getDeleted() == 0) {
pojoGroupInfo.setExtra(groupInfo.getExtra());
pojoGroupInfo.setName(groupInfo.getName());
pojoGroupInfo.setOwner(groupInfo.getOwner());
pojoGroupInfo.setPortrait(groupInfo.getPortrait());
pojoGroupInfo.setTarget_id(groupInfo.getTargetId());
pojoGroupInfo.setType(groupInfo.getType());
pojoGroupInfo.setMute(groupInfo.getMute());
pojoGroupInfo.setJoin_type(groupInfo.getJoinType());
pojoGroupInfo.setPrivate_chat(groupInfo.getPrivateChat());
pojoGroupInfo.setSearchable(groupInfo.getSearchable());
pojoGroupInfo.setMax_member_count(groupInfo.getMemberCount());
pojoGroupInfo.setHistory_message(groupInfo.getHistoryMessage());
pojoGroupInfo.setSuper_group(groupInfo.getSuperGroup()>0);
}
m_Server.getCallbackScheduler().execute(() -> { m_Server.getCallbackScheduler().execute(() -> {
try { try {
HttpUtils.httpJsonPost(mGroupInfoUpdateCallback, GsonUtil.gson.toJson(event), HttpUtils.HttpPostType.POST_TYPE_Grout_Event_Callback); HttpUtils.httpJsonPost(mGroupInfoUpdateCallback, GsonUtil.gson.toJson(event), HttpUtils.HttpPostType.POST_TYPE_Grout_Event_Callback);
@@ -1525,8 +1756,19 @@ public class MemoryMessagesStore implements IMessagesStore {
WFCMessage.GroupMember newOwner = null; WFCMessage.GroupMember newOwner = null;
for (WFCMessage.GroupMember member :members) { for (WFCMessage.GroupMember member :members) {
if (!member.getMemberId().equals(operator) && member.getType() != GroupMemberType_Removed) { if (!member.getMemberId().equals(operator) && member.getType() != GroupMemberType_Removed) {
newOwner = member; if(newOwner == null) {
break; newOwner = member;
} else {
if(newOwner.getType() == GroupMemberType_Silent && member.getType() != GroupMemberType_Silent) {
newOwner = member;
} else if(newOwner.getType() != GroupMemberType_Manager && member.getType() == GroupMemberType_Manager) {
newOwner = member;
} else if(newOwner.getType() == member.getType()) {
if(newOwner.getCreateDt() > member.getCreateDt() && member.getCreateDt() > 0) {
newOwner = member;
}
}
}
} }
} }
@@ -1620,7 +1862,7 @@ public class MemoryMessagesStore implements IMessagesStore {
removeFavGroup(groupId, ids); removeFavGroup(groupId, ids);
removeGroupUserSettings(groupId, ids); removeGroupUserSettings(groupId, ids);
callbackGroupEvent(operator, groupId, ProtoConstants.GroupUpdateEventType.Group_Event_Destroy); callbackGroupEvent(operator, groupId, ProtoConstants.GroupUpdateEventType.Group_Event_Destroy, groupInfo);
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -1705,12 +1947,12 @@ public class MemoryMessagesStore implements IMessagesStore {
if (modifyType == Modify_Group_Mute) { if (modifyType == Modify_Group_Mute) {
if (newInfoBuilder.getMute() > 0) { if (newInfoBuilder.getMute() > 0) {
callbackGroupEvent(operator, groupId, ProtoConstants.GroupUpdateEventType.Group_Event_Mute); callbackGroupEvent(operator, groupId, ProtoConstants.GroupUpdateEventType.Group_Event_Mute, newInfoBuilder.build());
} else { } else {
callbackGroupEvent(operator, groupId, ProtoConstants.GroupUpdateEventType.Group_Event_Unmute); callbackGroupEvent(operator, groupId, ProtoConstants.GroupUpdateEventType.Group_Event_Unmute, newInfoBuilder.build());
} }
} else { } else {
callbackGroupEvent(operator, groupId, ProtoConstants.GroupUpdateEventType.Group_Event_Update); callbackGroupEvent(operator, groupId, ProtoConstants.GroupUpdateEventType.Group_Event_Update, newInfoBuilder.build());
} }
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -1723,7 +1965,7 @@ public class MemoryMessagesStore implements IMessagesStore {
WFCMessage.GroupInfo groupInfo = mIMap.get(groupId); WFCMessage.GroupInfo groupInfo = mIMap.get(groupId);
if (groupInfo == null) { if (groupInfo == null) {
groupInfo = databaseStore.getPersistGroupInfo(groupId); groupInfo = databaseStore.getPersistGroupInfo(groupId);
if (groupInfo != null) { if (groupInfo != null && groupInfo.getDeleted() == 0) {
mIMap.set(groupId, groupInfo); mIMap.set(groupId, groupInfo);
} else { } else {
return ErrorCode.ERROR_CODE_NOT_EXIST; return ErrorCode.ERROR_CODE_NOT_EXIST;
@@ -1808,7 +2050,7 @@ public class MemoryMessagesStore implements IMessagesStore {
WFCMessage.GroupInfo groupInfo = mIMap.get(groupId); WFCMessage.GroupInfo groupInfo = mIMap.get(groupId);
if (groupInfo == null) { if (groupInfo == null) {
groupInfo = databaseStore.getPersistGroupInfo(groupId); groupInfo = databaseStore.getPersistGroupInfo(groupId);
if (groupInfo != null) { if (groupInfo != null && groupInfo.getDeleted() == 0) {
mIMap.set(groupId, groupInfo); mIMap.set(groupId, groupInfo);
} else { } else {
return ErrorCode.ERROR_CODE_NOT_EXIST; return ErrorCode.ERROR_CODE_NOT_EXIST;
@@ -1892,16 +2134,12 @@ public class MemoryMessagesStore implements IMessagesStore {
ArrayList<WFCMessage.GroupInfo> out = new ArrayList<>(); ArrayList<WFCMessage.GroupInfo> out = new ArrayList<>();
for (WFCMessage.UserRequest request : requests) { for (WFCMessage.UserRequest request : requests) {
WFCMessage.GroupInfo groupInfo = mIMap.get(request.getUid()); WFCMessage.GroupInfo groupInfo = mIMap.get(request.getUid());
if (groupInfo == null) {
groupInfo = databaseStore.getPersistGroupInfo(request.getUid());
if (groupInfo != null) {
mIMap.set(request.getUid(), groupInfo);
}
}
if (groupInfo != null && groupInfo.getUpdateDt() > request.getUpdateDt()) { if (groupInfo != null && groupInfo.getUpdateDt() > request.getUpdateDt()) {
if(!isAdmin && !StringUtil.isNullOrEmpty(fromUser)) { if(!isAdmin && !StringUtil.isNullOrEmpty(fromUser) && groupInfo.getDeleted() == 0) {
WFCMessage.GroupMember gm = getGroupMember(groupInfo.getTargetId(), fromUser); WFCMessage.GroupMember gm = getGroupMember(groupInfo.getTargetId(), fromUser);
if((gm == null || gm.getType() == GroupMemberType_Removed) && request.getUpdateDt() > 0) {
continue;
}
if(gm == null) { if(gm == null) {
groupInfo = groupInfo.toBuilder().setMemberUpdateDt(-1).build(); groupInfo = groupInfo.toBuilder().setMemberUpdateDt(-1).build();
} else if(gm.getType() == GroupMemberType_Removed) { } else if(gm.getType() == GroupMemberType_Removed) {
@@ -1929,6 +2167,11 @@ public class MemoryMessagesStore implements IMessagesStore {
return databaseStore.getUserGroupIds(userId); return databaseStore.getUserGroupIds(userId);
} }
@Override
public Set<String> getUserGroupIds(String userId, List<Integer> memberTypes) {
return databaseStore.getUserGroupIds(userId, memberTypes);
}
@Override @Override
public Set<String> getCommonGroupIds(String userId1, String userId2) { public Set<String> getCommonGroupIds(String userId1, String userId2) {
return databaseStore.getCommonGroupIds(userId1, userId2); return databaseStore.getCommonGroupIds(userId1, userId2);
@@ -2052,7 +2295,7 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
} }
callbackGroupEvent(operator, groupId, ProtoConstants.GroupUpdateEventType.Group_Event_Transfer); callbackGroupEvent(operator, groupId, ProtoConstants.GroupUpdateEventType.Group_Event_Transfer, groupInfo);
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -2124,7 +2367,7 @@ public class MemoryMessagesStore implements IMessagesStore {
IMap<String, WFCMessage.GroupInfo> groups = hzInstance.getMap(GROUPS_MAP); IMap<String, WFCMessage.GroupInfo> groups = hzInstance.getMap(GROUPS_MAP);
WFCMessage.GroupInfo groupInfo = groups.get(groupId); WFCMessage.GroupInfo groupInfo = groups.get(groupId);
boolean isMute = false; boolean isMute = false;
if (groupInfo != null) { if (groupInfo != null && groupInfo.getDeleted() == 0) {
if (groupInfo.getOwner().equals(memberId)) { if (groupInfo.getOwner().equals(memberId)) {
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -2209,10 +2452,32 @@ public class MemoryMessagesStore implements IMessagesStore {
WFCMessage.GroupInfo groupInfo = groupMap.get(message.getConversation().getTarget()); WFCMessage.GroupInfo groupInfo = groupMap.get(message.getConversation().getTarget());
if (groupInfo == null) { if (groupInfo == null) {
return ErrorCode.ERROR_CODE_RECALL_TIME_EXPIRED; LOG.info("recall message failure, group {} not exist", message.getConversation().getTarget());
return ErrorCode.ERROR_CODE_NOT_EXIST;
} }
if (operatorId.equals(groupInfo.getOwner())) { if (operatorId.equals(groupInfo.getOwner())) {
canRecall = true; if(operatorId.equals(message.getFromUser())) {
if(mGroupAllowOwnerRecallSelfMsg) {
canRecall = true;
}
} else {
canRecall = true;
}
} else {
if(message.getFromUser().equals(operatorId) && mGroupAllowManagerRecallSelfMsg) {
MultiMap<String, WFCMessage.GroupMember> groupMembers = hzInstance.getMultiMap(GROUP_MEMBERS);
Collection<WFCMessage.GroupMember> members = groupMembers.get(message.getConversation().getTarget());
if (members == null || members.size() == 0) {
members = loadGroupMemberFromDB(hzInstance, message.getConversation().getTarget());
}
for (WFCMessage.GroupMember member : members) {
if (member.getMemberId().equals(operatorId)) {
if (member.getType() == GroupMemberType_Manager || member.getType() == ProtoConstants.GroupMemberType.GroupMemberType_Owner) {
canRecall = true;
}
}
}
}
} }
if(!canRecall && !message.getFromUser().equals(operatorId)) { if(!canRecall && !message.getFromUser().equals(operatorId)) {
@@ -2560,6 +2825,7 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
String pcValue = null; String pcValue = null;
String padValue = null;
for (MemorySessionStore.Session s : m_Server.getStore().sessionsStore().sessionForUser(session.username)) { for (MemorySessionStore.Session s : m_Server.getStore().sessionsStore().sessionForUser(session.username)) {
if (s.getDeleted() != 0 || !m_Server.getConnectionsManager().isConnected(s.getClientID())) { if (s.getDeleted() != 0 || !m_Server.getConnectionsManager().isConnected(s.getClientID())) {
continue; continue;
@@ -2569,8 +2835,14 @@ public class MemoryMessagesStore implements IMessagesStore {
case Platform_LINUX: case Platform_LINUX:
case Platform_Windows: case Platform_Windows:
case Platform_OSX: case Platform_OSX:
case Platform_HarmonyPC:
pcValue = System.currentTimeMillis() + "|" + s.getPlatform() + "|" + s.getClientID() + "|" + s.getPhoneName(); pcValue = System.currentTimeMillis() + "|" + s.getPlatform() + "|" + s.getClientID() + "|" + s.getPhoneName();
break; break;
case Platform_iPad:
case Platform_APad:
case Platform_HarmonyPad:
padValue = System.currentTimeMillis() + "|" + s.getPlatform() + "|" + s.getClientID() + "|" + s.getPhoneName();
break;
default: default:
break; break;
} }
@@ -2580,6 +2852,11 @@ public class MemoryMessagesStore implements IMessagesStore {
if (!isOnlineValueEqual(pcentry, pcValue)) { if (!isOnlineValueEqual(pcentry, pcValue)) {
updateUserSettings(session.username, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("PC").setValue(pcValue==null?"":pcValue).build(), session.clientID); updateUserSettings(session.username, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("PC").setValue(pcValue==null?"":pcValue).build(), session.clientID);
} }
WFCMessage.UserSettingEntry padentry = getUserSetting(session.getUsername(), kUserSettingPCOnline, "Pad");
if (!isOnlineValueEqual(padentry, padValue)) {
updateUserSettings(session.username, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("Pad").setValue(padValue==null?"":padValue).build(), session.clientID);
}
} }
@Override @Override
@@ -2613,7 +2890,9 @@ public class MemoryMessagesStore implements IMessagesStore {
IMap<String, Integer> mUserMap = hzInstance.getMap(USER_STATUS); IMap<String, Integer> mUserMap = hzInstance.getMap(USER_STATUS);
ArrayList<InputOutputUserBlockStatus> out = new ArrayList<>(); ArrayList<InputOutputUserBlockStatus> out = new ArrayList<>();
for (Map.Entry<String, Integer> entry : mUserMap.entrySet()) { for (Map.Entry<String, Integer> entry : mUserMap.entrySet()) {
out.add(new InputOutputUserBlockStatus(entry.getKey(), entry.getValue())); if(entry.getValue() > 0) {
out.add(new InputOutputUserBlockStatus(entry.getKey(), entry.getValue()));
}
} }
return out; return out;
} }
@@ -2678,7 +2957,7 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
@Override @Override
public void addUserInfo(WFCMessage.User user, String password) throws Exception { public void addUserInfo(WFCMessage.User user) throws Exception {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance(); HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
IMap<String, WFCMessage.User> mUserMap = hzInstance.getMap(USERS); IMap<String, WFCMessage.User> mUserMap = hzInstance.getMap(USERS);
if (databaseStore.isUidAndNameConflict(user.getUid(), user.getName())) { if (databaseStore.isUidAndNameConflict(user.getUid(), user.getName())) {
@@ -2686,7 +2965,6 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
databaseStore.updateUser(user); databaseStore.updateUser(user);
mUserMap.put(user.getUid(), user); mUserMap.put(user.getUid(), user);
databaseStore.updateUserPassword(user.getUid(), password);
callbackUserInfoEvent(user); callbackUserInfoEvent(user);
} }
@@ -2772,6 +3050,11 @@ public class MemoryMessagesStore implements IMessagesStore {
return getUserInfo(userId); return getUserInfo(userId);
} }
@Override
public List<WFCMessage.User> getUserInfosByEmail(String email) {
return databaseStore.getUserInfosByEmail(email);
}
@Override @Override
public List<WFCMessage.User> getUserInfoList(int count, int offset) { public List<WFCMessage.User> getUserInfoList(int count, int offset) {
return databaseStore.getAllUsers(count, offset); return databaseStore.getAllUsers(count, offset);
@@ -2784,9 +3067,21 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
if (mDisableNicknameSearch && searchType == ProtoConstants.SearchUserType.SearchUserType_General) { if (mDisableNicknameSearch && searchType == ProtoConstants.SearchUserType.SearchUserType_General) {
searchType = ProtoConstants.SearchUserType.SearchUserType_Name_Mobile_UserId;
}
if(mDisableUserIdSearch && searchType == ProtoConstants.SearchUserType.SearchUserType_Name_Mobile_UserId) {
searchType = ProtoConstants.SearchUserType.SearchUserType_Name_Mobile; searchType = ProtoConstants.SearchUserType.SearchUserType_Name_Mobile;
} }
if(mDisableUserIdSearch && searchType == ProtoConstants.SearchUserType.SearchUserType_General) {
searchType = ProtoConstants.SearchUserType.SearchUserType_Name_Mobile_DisplayName;
}
if(mDisableUserIdSearch && searchType == ProtoConstants.SearchUserType.SearchUserType_UserId) {
return new ArrayList<>();
}
return databaseStore.searchUserFromDB(keyword, searchType, page); return databaseStore.searchUserFromDB(keyword, searchType, page);
} }
@@ -2914,7 +3209,7 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
@Override @Override
public ErrorCode isAllowUserMessage(String targetUser, String fromUser) { public ErrorCode isAllowUserMessage(String targetUser, String fromUser, int line) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance(); HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
MultiMap<String, FriendData> friendsMap = hzInstance.getMultiMap(USER_FRIENDS); MultiMap<String, FriendData> friendsMap = hzInstance.getMultiMap(USER_FRIENDS);
@@ -2941,7 +3236,7 @@ public class MemoryMessagesStore implements IMessagesStore {
if (mDisableStrangerChat) { if (mDisableStrangerChat) {
//在禁止私聊时,是否是允许私聊的用户id //在禁止私聊时,是否是允许私聊的用户id
if(mAllowStrangerChatSet.contains(targetUser)) { if(mAllowStrangerChatSet.contains(targetUser) || mAllowStrangerChatSet.contains(fromUser) || mAllowStrangerLineSet.contains(line)) {
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -2965,6 +3260,30 @@ public class MemoryMessagesStore implements IMessagesStore {
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@Override
public ErrorCode isBlacked(String fromUser, String userId) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
MultiMap<String, FriendData> friendsMap = hzInstance.getMultiMap(USER_FRIENDS);
Collection<FriendData> friendDatas = friendsMap.get(fromUser);
if (friendDatas == null || friendDatas.size() == 0) {
friendDatas = loadFriend(friendsMap, fromUser);
}
for (FriendData friendData : friendDatas) {
if (friendData.getFriendUid().equals(userId)) {
if (friendData.getBlacked() == 1) {
return ErrorCode.ERROR_CODE_IN_BLACK_LIST;
} else {
break;
}
}
}
return ErrorCode.ERROR_CODE_SUCCESS;
}
synchronized Collection<FriendData> loadFriend(MultiMap<String, FriendData> friendsMap, String userId) { synchronized Collection<FriendData> loadFriend(MultiMap<String, FriendData> friendsMap, String userId) {
Collection<FriendData> friends = databaseStore.getPersistFriends(userId); Collection<FriendData> friends = databaseStore.getPersistFriends(userId);
if (friends != null) { if (friends != null) {
@@ -3082,13 +3401,29 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
@Override @Override
public ErrorCode saveAddFriendRequest(String userId, WFCMessage.AddFriendRequest request, long[] head, boolean isAdmin) { public ErrorCode saveAddFriendRequest(String userId, WFCMessage.AddFriendRequest request, long[] head, boolean isAdmin, boolean isRobot) {
if (!isAdmin && mDisableFriendRequest) { if (!isAdmin && mDisableFriendRequest) {
return ErrorCode.ERROR_CODE_NOT_RIGHT; return ErrorCode.ERROR_CODE_NOT_RIGHT;
} }
if(!isRobot && !isAdmin && mFriendRateLimiter != null) {
if(!mFriendRateLimiter.isGranted(userId)) {
LOG.error("User {} request add friend over frequency", userId);
return ErrorCode.ERROR_CODE_OVER_FREQUENCY;
}
}
HazelcastInstance hzInstance = m_Server.getHazelcastInstance(); HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
MultiMap<String, WFCMessage.FriendRequest> requestMap = hzInstance.getMultiMap(USER_FRIENDS_REQUEST); MultiMap<String, WFCMessage.FriendRequest> requestMap = hzInstance.getMultiMap(USER_FRIENDS_REQUEST);
WFCMessage.UserSettingEntry userSettingData = getUserSetting(request.getTargetUid(), kUserSettingAddFriendStrategy, "");
boolean noVerify = userSettingData != null && "1".equals(userSettingData.getValue());
boolean noAllow = userSettingData != null && "2".equals(userSettingData.getValue());
if(noAllow) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
}
Collection<WFCMessage.FriendRequest> requests = requestMap.get(userId); Collection<WFCMessage.FriendRequest> requests = requestMap.get(userId);
if (requests == null || requests.size() == 0) { if (requests == null || requests.size() == 0) {
requests = loadFriendRequest(requestMap, userId); requests = loadFriendRequest(requestMap, userId);
@@ -3103,17 +3438,27 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
} }
boolean alreadyExist = false; if (!noVerify && existRequest != null && existRequest.getStatus() != ProtoConstants.FriendRequestStatus.RequestStatus_Accepted && !isAdmin) {
if (existRequest != null && existRequest.getStatus() != ProtoConstants.FriendRequestStatus.RequestStatus_Accepted && !isAdmin) { if (existRequest.getStatus() == ProtoConstants.FriendRequestStatus.RequestStatus_Rejected
alreadyExist = true; && System.currentTimeMillis() - existRequest.getUpdateDt() < mFriendRejectDuration) {
if (mFriendRequestDuration > 0 && System.currentTimeMillis() - existRequest.getUpdateDt() > mFriendRequestDuration) { return ErrorCode.ERROR_CODE_FRIEND_REQUEST_BLOCKED;
if (existRequest.getStatus() == ProtoConstants.FriendRequestStatus.RequestStatus_Rejected }
&& System.currentTimeMillis() - existRequest.getUpdateDt() < mFriendRejectDuration) {
return ErrorCode.ERROR_CODE_FRIEND_REQUEST_BLOCKED; if (!(mFriendRequestDuration > 0 && System.currentTimeMillis() - existRequest.getUpdateDt() > mFriendRequestDuration)) {
}
} else {
if(System.currentTimeMillis() - existRequest.getUpdateDt() > 5 * 60 * 1000) { if(System.currentTimeMillis() - existRequest.getUpdateDt() > 5 * 60 * 1000) {
return ErrorCode.ERROR_CODE_FRIEND_ALREADY_REQUEST; return ErrorCode.ERROR_CODE_FRIEND_ALREADY_REQUEST;
} else {
mWriteLock.lock();
try {
String repeatKey = userId + "-" + existRequest.getToUid();
Long lastTime = repeatFriendRequest.get(repeatKey);
if(lastTime != null && System.currentTimeMillis() - lastTime < 5 * 60 * 1000) {
return ErrorCode.ERROR_CODE_FRIEND_ALREADY_REQUEST;
}
repeatFriendRequest.put(repeatKey, System.currentTimeMillis());
} finally {
mWriteLock.unlock();
}
} }
} }
} }
@@ -3135,14 +3480,20 @@ public class MemoryMessagesStore implements IMessagesStore {
.setReason(request.getReason()) .setReason(request.getReason())
.setExtra(request.getExtra()) .setExtra(request.getExtra())
.setStatus(ProtoConstants.FriendRequestStatus.RequestStatus_Sent) .setStatus(ProtoConstants.FriendRequestStatus.RequestStatus_Sent)
.setToReadStatus(false) .setToReadStatus(noVerify)
.setUpdateDt(alreadyExist ? existRequest.getUpdateDt() : System.currentTimeMillis()) .setUpdateDt(System.currentTimeMillis())
.build(); .build();
databaseStore.persistOrUpdateFriendRequest(newRequest); databaseStore.persistOrUpdateFriendRequest(newRequest);
requestMap.remove(userId); requestMap.remove(userId);
requestMap.remove(request.getTargetUid()); requestMap.remove(request.getTargetUid());
if(noVerify) {
WFCMessage.HandleFriendRequest handleFriendRequest = WFCMessage.HandleFriendRequest.newBuilder().setTargetUid(userId).setStatus(ProtoConstants.FriendRequestStatus.RequestStatus_Accepted).build();
ServerAPIHelper.sendRequest(request.getTargetUid(), null, IMTopic.HandleFriendRequestTopic, handleFriendRequest.toByteArray(), null, ProtoConstants.RequestSourceType.Request_From_User);
}
head[0] = newRequest.getUpdateDt(); head[0] = newRequest.getUpdateDt();
return ErrorCode.ERROR_CODE_SUCCESS; return ErrorCode.ERROR_CODE_SUCCESS;
} }
@@ -3466,9 +3817,25 @@ public class MemoryMessagesStore implements IMessagesStore {
} }
} }
MultiMap<String, UserClientEntry> chatroomMembers = m_Server.getHazelcastInstance().getMultiMap(CHATROOM_MEMBER_IDS);
String alreadyInChatroom = (String) m_Server.getHazelcastInstance().getMap(USER_CHATROOM).get(userId);
if(alreadyInChatroom != null) {
for (UserClientEntry userClientEntry : chatroomMembers.get(alreadyInChatroom)) {
if(userClientEntry.userId.equals(userId)) {
if(!chatroomId.equals(alreadyInChatroom) || !userClientEntry.clientId.equals(clientId)) {
if(mChatroomKickoffOtherPlatform) {
handleQuitChatroom(userId, userClientEntry.clientId, chatroomId);
} else {
return ErrorCode.ERROR_CODE_OTHER_CLIENT_ALREADY_IN_CHATROOM;
}
}
}
}
}
m_Server.getStore().sessionsStore().getSession(clientId).refreshLastChatroomActiveTime(); m_Server.getStore().sessionsStore().getSession(clientId).refreshLastChatroomActiveTime();
m_Server.getHazelcastInstance().getMap(USER_CHATROOM).put(userId, chatroomId); m_Server.getHazelcastInstance().getMap(USER_CHATROOM).put(userId, chatroomId);
m_Server.getHazelcastInstance().getMultiMap(CHATROOM_MEMBER_IDS).put(chatroomId, new UserClientEntry(userId, clientId)); chatroomMembers.put(chatroomId, new UserClientEntry(userId, clientId));
mWriteLock.lock(); mWriteLock.lock();
chatroomMessages.put(userId, new TreeMap<>()); chatroomMessages.put(userId, new TreeMap<>());
@@ -4247,6 +4614,35 @@ public class MemoryMessagesStore implements IMessagesStore {
return getChannelListener(channelId); return getChannelListener(channelId);
} }
@Override
public int getOnlineUserCount() {
return m_Server.getProcessor().getConnectionDescriptors().getActiveConnectionsNo();
}
@Override
public GetOnlineUserResult getOnlineUsers(int offset, int count) {
List<String> onlineUserIds = new ArrayList<>(m_Server.getProcessor().getConnectionDescriptors().getConnectedClientIds());
GetOnlineUserResult result = new GetOnlineUserResult();
result.userClients = new ArrayList<>();
result.totalCount = onlineUserIds.size();
result.offset = offset;
if(onlineUserIds.size() > offset) {
List<String> clientIds = onlineUserIds.subList(offset, Math.min(offset+count, onlineUserIds.size()));
for (String clientId : clientIds) {
MemorySessionStore.Session session = m_Server.getStore().sessionsStore().getSession(clientId);
if(session != null) {
GetOnlineUserResult.UserClient userClient = new GetOnlineUserResult.UserClient();
userClient.userId = session.getUsername();
userClient.clientId = session.getClientID();
userClient.platform = session.getPlatform();
result.userClients.add(userClient);
}
}
}
return result;
}
@Override @Override
public Set<String> handleSensitiveWord(String message) { public Set<String> handleSensitiveWord(String message) {
updateSensitiveWord(); updateSensitiveWord();
@@ -4324,11 +4720,26 @@ public class MemoryMessagesStore implements IMessagesStore {
return mChannelCallbackWithClientInfo; return mChannelCallbackWithClientInfo;
} }
@Override
public boolean isChannelNewCallbackFeature() {
return mChannelNewCallbackFeature;
}
@Override @Override
public boolean isRobotAutoAcceptFriendRequest() { public boolean isRobotAutoAcceptFriendRequest() {
return mFriendRobotAutoAccept; return mFriendRobotAutoAccept;
} }
@Override
public long getPushExpiredTimes() {
return mPushExpiredTimes;
}
@Override
public Set<Integer> getForcePushTypes() {
return mForcePushTypes;
}
@Override @Override
public List<Integer> getClientForbiddenSendTypes() { public List<Integer> getClientForbiddenSendTypes() {
return mForbiddenClientSendTypes; return mForbiddenClientSendTypes;
@@ -4447,9 +4858,11 @@ public class MemoryMessagesStore implements IMessagesStore {
@Override @Override
public String getShortUUID(){ public String getShortUUID(){
int id = databaseStore.getGeneratedId(); if(!mIDUseUUID) {
if (id > 0) { int id = databaseStore.getGeneratedId();
return IDUtils.toUid(id); if (id > 0) {
return IDUtils.toUid(id);
}
} }
return UUIDGenerator.getUUID(); return UUIDGenerator.getUUID();
} }
@@ -40,6 +40,7 @@ public class MemorySessionStore implements ISessionsStore {
private boolean supportMultiEndpoint = false; private boolean supportMultiEndpoint = false;
private boolean supportMultiPCEndpoint = false; private boolean supportMultiPCEndpoint = false;
private boolean supportMultiPadEndpoint = false;
private boolean clientSupportKickoff = false; private boolean clientSupportKickoff = false;
public static class Session implements Comparable<Session>{ public static class Session implements Comparable<Session>{
@@ -292,6 +293,10 @@ public class MemorySessionStore implements ISessionsStore {
supportMultiPCEndpoint = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_MULTI_PC_ENDPOINT, "false")); supportMultiPCEndpoint = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_MULTI_PC_ENDPOINT, "false"));
} catch (Exception e) { } catch (Exception e) {
} }
try {
supportMultiPadEndpoint = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_MULTI_PAD_ENDPOINT, "false"));
} catch (Exception e) {
}
try { try {
clientSupportKickoff = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_CLIENT_SUPPORT_KICKOFF_EVENT, "false")); clientSupportKickoff = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_CLIENT_SUPPORT_KICKOFF_EVENT, "false"));
@@ -396,6 +401,10 @@ public class MemorySessionStore implements ISessionsStore {
&& !(platform == ProtoConstants.Platform.Platform_Windows && supportMultiPCEndpoint) && !(platform == ProtoConstants.Platform.Platform_Windows && supportMultiPCEndpoint)
&& !(platform == ProtoConstants.Platform.Platform_LINUX && supportMultiPCEndpoint) && !(platform == ProtoConstants.Platform.Platform_LINUX && supportMultiPCEndpoint)
&& !(platform == ProtoConstants.Platform.Platform_OSX && supportMultiPCEndpoint) && !(platform == ProtoConstants.Platform.Platform_OSX && supportMultiPCEndpoint)
&& !(platform == ProtoConstants.Platform.Platform_HarmonyPC && supportMultiPCEndpoint)
&& !(platform == ProtoConstants.Platform.Platform_iPad && supportMultiPadEndpoint)
&& !(platform == ProtoConstants.Platform.Platform_APad && supportMultiPadEndpoint)
&& !(platform == ProtoConstants.Platform.Platform_HarmonyPad && supportMultiPadEndpoint)
) { ) {
databaseStore.clearMultiEndpoint(username, clientID, platform); databaseStore.clearMultiEndpoint(username, clientID, platform);
if (userSessions.get(username) != null) { if (userSessions.get(username) != null) {
@@ -410,15 +419,19 @@ public class MemorySessionStore implements ISessionsStore {
} }
boolean remove = false; boolean remove = false;
if (platform == ProtoConstants.Platform.Platform_Android || platform == ProtoConstants.Platform.Platform_iOS) { if (platform == ProtoConstants.Platform.Platform_Android || platform == ProtoConstants.Platform.Platform_iOS || platform == ProtoConstants.Platform.Platform_Harmony) {
if (s.getPlatform() == ProtoConstants.Platform.Platform_Android || s.getPlatform() == ProtoConstants.Platform.Platform_iOS) { if (s.getPlatform() == ProtoConstants.Platform.Platform_Android || s.getPlatform() == ProtoConstants.Platform.Platform_iOS || s.getPlatform() == ProtoConstants.Platform.Platform_Harmony) {
remove = true; remove = true;
} }
} else if(platform == ProtoConstants.Platform.Platform_OSX || platform == ProtoConstants.Platform.Platform_Windows || platform == ProtoConstants.Platform.Platform_LINUX) { } else if(platform == ProtoConstants.Platform.Platform_iPad || platform == ProtoConstants.Platform.Platform_APad || platform == ProtoConstants.Platform.Platform_HarmonyPad) {
if (s.getPlatform() == ProtoConstants.Platform.Platform_OSX || s.getPlatform() == ProtoConstants.Platform.Platform_Windows || s.getPlatform() == ProtoConstants.Platform.Platform_LINUX) { if (s.getPlatform() == ProtoConstants.Platform.Platform_iPad || s.getPlatform() == ProtoConstants.Platform.Platform_APad || s.getPlatform() == ProtoConstants.Platform.Platform_HarmonyPad) {
remove = true; remove = true;
} }
} else { } else if(platform == ProtoConstants.Platform.Platform_OSX || platform == ProtoConstants.Platform.Platform_Windows || platform == ProtoConstants.Platform.Platform_LINUX || platform == ProtoConstants.Platform.Platform_HarmonyPC) {
if (s.getPlatform() == ProtoConstants.Platform.Platform_OSX || s.getPlatform() == ProtoConstants.Platform.Platform_Windows || s.getPlatform() == ProtoConstants.Platform.Platform_LINUX || s.getPlatform() == ProtoConstants.Platform.Platform_HarmonyPC) {
remove = true;
}
} else { //web, microapp
if (s.getPlatform() ==platform) { if (s.getPlatform() ==platform) {
remove = true; remove = true;
} }
@@ -615,6 +628,11 @@ public class MemorySessionStore implements ISessionsStore {
return result; return result;
} }
@Override
public boolean isClientOnline(String clientId) {
return mServer.getProcessor().getConnectionDescriptors().isConnected(clientId);
}
@Override @Override
public StoredMessage inFlightAck(String clientID, int messageID) { public StoredMessage inFlightAck(String clientID, int messageID) {
return getSession(clientID).outboundFlightMessages.remove(messageID); return getSession(clientID).outboundFlightMessages.remove(messageID);
@@ -742,7 +760,12 @@ public class MemorySessionStore implements ISessionsStore {
if (session.getPlatform() == ProtoConstants.Platform.Platform_LINUX if (session.getPlatform() == ProtoConstants.Platform.Platform_LINUX
|| session.getPlatform() == ProtoConstants.Platform.Platform_WEB || session.getPlatform() == ProtoConstants.Platform.Platform_WEB
|| session.getPlatform() == ProtoConstants.Platform.Platform_Windows || session.getPlatform() == ProtoConstants.Platform.Platform_Windows
|| session.getPlatform() == ProtoConstants.Platform.Platform_OSX) { || session.getPlatform() == ProtoConstants.Platform.Platform_OSX
|| session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyPC
|| session.getPlatform() == ProtoConstants.Platform.Platform_iPad
|| session.getPlatform() == ProtoConstants.Platform.Platform_APad
|| session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyPad
) {
databaseStore.updateSessionDeleted(operator, pcClientId, 1); databaseStore.updateSessionDeleted(operator, pcClientId, 1);
sessions.remove(pcClientId); sessions.remove(pcClientId);
mServer.getProcessor().kickoffSession(session); mServer.getProcessor().kickoffSession(session);
@@ -140,7 +140,7 @@ public class Server {
Runtime.getRuntime().addShutdownHook(new Thread(instance::stopServer)); Runtime.getRuntime().addShutdownHook(new Thread(instance::stopServer));
Runtime.getRuntime().addShutdownHook(new Thread(httpServer::shutdown)); Runtime.getRuntime().addShutdownHook(new Thread(httpServer::shutdown));
System.out.println("Wildfire IM server start success..."); System.out.println("Wildfire IM server start success.");
} }
/** /**
@@ -357,7 +357,11 @@ public class Server {
private String getServerIp(IConfig config) { private String getServerIp(IConfig config) {
String serverIp = config.getProperty(BrokerConstants.SERVER_IP_PROPERTY_NAME); String serverIp = config.getProperty(BrokerConstants.SERVER_IP_PROPERTY_NAME);
if (serverIp == null || serverIp.equals("0.0.0.0")) { if (serverIp == null || serverIp.equals("0.0.0.0")) {
serverIp = Utility.getLocalAddress().getHostAddress(); if(Utility.getLocalAddress() != null) {
serverIp = Utility.getLocalAddress().getHostAddress();
} else {
serverIp = "0.0.0.0";
}
} }
return serverIp; return serverIp;
} }
@@ -135,7 +135,6 @@ public class NettyAcceptor implements ServerAcceptor {
} }
} }
}) })
.option(ChannelOption.SO_BACKLOG, 10240) // 服务端可连接队列大小
.option(ChannelOption.SO_BACKLOG, nettySoBacklog) .option(ChannelOption.SO_BACKLOG, nettySoBacklog)
.option(ChannelOption.SO_REUSEADDR, nettySoReuseaddr) .option(ChannelOption.SO_REUSEADDR, nettySoReuseaddr)
.childOption(ChannelOption.TCP_NODELAY, nettyTcpNodelay) .childOption(ChannelOption.TCP_NODELAY, nettyTcpNodelay)
@@ -16,12 +16,10 @@
package io.moquette.spi; package io.moquette.spi;
import cn.wildfirechat.pojos.InputOutputUserInfo; import cn.wildfirechat.pojos.*;
import cn.wildfirechat.pojos.SystemSettingPojo;
import cn.wildfirechat.proto.ProtoConstants; import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage; import cn.wildfirechat.proto.WFCMessage;
import com.xiaoleilu.loServer.model.FriendData; import com.xiaoleilu.loServer.model.FriendData;
import cn.wildfirechat.pojos.InputOutputUserBlockStatus;
import io.moquette.persistence.DatabaseStore; import io.moquette.persistence.DatabaseStore;
import io.moquette.persistence.MemorySessionStore; import io.moquette.persistence.MemorySessionStore;
import io.moquette.persistence.UserClientEntry; import io.moquette.persistence.UserClientEntry;
@@ -31,10 +29,7 @@ import io.netty.buffer.Unpooled;
import io.netty.handler.codec.mqtt.MqttQoS; import io.netty.handler.codec.mqtt.MqttQoS;
import cn.wildfirechat.common.ErrorCode; import cn.wildfirechat.common.ErrorCode;
import java.util.Collection; import java.util.*;
import java.util.Date;
import java.util.List;
import java.util.Set;
/** /**
* Defines the SPI to be implemented by a StorageService that handle persistence of messages * Defines the SPI to be implemented by a StorageService that handle persistence of messages
@@ -107,6 +102,7 @@ public interface IMessagesStore {
WFCMessage.PullMessageResult fetchMessage(String user, String exceptClientId, long fromMessageId, int pullType); WFCMessage.PullMessageResult fetchMessage(String user, String exceptClientId, long fromMessageId, int pullType);
WFCMessage.PullMessageResult loadRemoteMessages(String user, WFCMessage.Conversation conversation, long beforeUid, int count, Collection<Integer> contentTypes); WFCMessage.PullMessageResult loadRemoteMessages(String user, WFCMessage.Conversation conversation, long beforeUid, int count, Collection<Integer> contentTypes);
long insertUserMessages(String sender, int conversationType, String target, int line, int messageContentType, String userId, long messageId, boolean directing); long insertUserMessages(String sender, int conversationType, String target, int line, int messageContentType, String userId, long messageId, boolean directing);
ErrorCode canAddGroupMembers(String operator, List<WFCMessage.GroupMember> memberList);
WFCMessage.GroupInfo createGroup(String operator, WFCMessage.GroupInfo groupInfo, List<WFCMessage.GroupMember> memberList, String memberExtra, boolean isAdmin); WFCMessage.GroupInfo createGroup(String operator, WFCMessage.GroupInfo groupInfo, List<WFCMessage.GroupMember> memberList, String memberExtra, boolean isAdmin);
ErrorCode addGroupMembers(String operator, boolean isAdmin, String groupId, List<WFCMessage.GroupMember> memberList, String extra); ErrorCode addGroupMembers(String operator, boolean isAdmin, String groupId, List<WFCMessage.GroupMember> memberList, String extra);
ErrorCode kickoffGroupMembers(String operator, boolean isAdmin, String groupId, List<String> memberList); ErrorCode kickoffGroupMembers(String operator, boolean isAdmin, String groupId, List<String> memberList);
@@ -119,6 +115,7 @@ public interface IMessagesStore {
List<WFCMessage.GroupInfo> getGroupInfos(List<WFCMessage.UserRequest> requests, String fromUser, boolean isAdmin); List<WFCMessage.GroupInfo> getGroupInfos(List<WFCMessage.UserRequest> requests, String fromUser, boolean isAdmin);
WFCMessage.GroupInfo getGroupInfo(String groupId); WFCMessage.GroupInfo getGroupInfo(String groupId);
Set<String> getUserGroupIds(String userId); Set<String> getUserGroupIds(String userId);
Set<String> getUserGroupIds(String userId, List<Integer> types);
Set<String> getCommonGroupIds(String userId1, String userId2); Set<String> getCommonGroupIds(String userId1, String userId2);
ErrorCode getGroupMembers(String fromUser, String groupId, long maxDt, List<WFCMessage.GroupMember> members); ErrorCode getGroupMembers(String fromUser, String groupId, long maxDt, List<WFCMessage.GroupMember> members);
WFCMessage.GroupMember getGroupMember(String groupId, String memberId); WFCMessage.GroupMember getGroupMember(String groupId, String memberId);
@@ -150,12 +147,13 @@ public interface IMessagesStore {
List<InputOutputUserBlockStatus> getUserStatusList(); List<InputOutputUserBlockStatus> getUserStatusList();
ErrorCode updateUserInfo(InputOutputUserInfo userInfo, int flag); ErrorCode updateUserInfo(InputOutputUserInfo userInfo, int flag);
void addUserInfo(WFCMessage.User user, String password) throws Exception; void addUserInfo(WFCMessage.User user) throws Exception;
void destroyUser(String userId); void destroyUser(String userId);
void updateUserInfo(WFCMessage.User user) throws Exception; void updateUserInfo(WFCMessage.User user) throws Exception;
WFCMessage.User getUserInfo(String userId); WFCMessage.User getUserInfo(String userId);
WFCMessage.User getUserInfoByName(String name); WFCMessage.User getUserInfoByName(String name);
WFCMessage.User getUserInfoByMobile(String mobile); WFCMessage.User getUserInfoByMobile(String mobile);
List<WFCMessage.User> getUserInfosByEmail(String email);
List<WFCMessage.User> searchUser(String keyword, int searchType, int page); List<WFCMessage.User> searchUser(String keyword, int searchType, int page);
List<WFCMessage.User> getUserInfoList(int count, int offset); List<WFCMessage.User> getUserInfoList(int count, int offset);
@@ -172,6 +170,7 @@ public interface IMessagesStore {
long insertChatroomMessages(String target, int line, long messageId); long insertChatroomMessages(String target, int line, long messageId);
Collection<UserClientEntry> getChatroomMembers(String chatroomId); Collection<UserClientEntry> getChatroomMembers(String chatroomId);
OutputUserChatroom getUserChatroom(String userId);
WFCMessage.PullMessageResult fetchChatroomMessage(String fromUser, String chatroomId, String exceptClientId, long fromMessageId); WFCMessage.PullMessageResult fetchChatroomMessage(String fromUser, String chatroomId, String exceptClientId, long fromMessageId);
ErrorCode verifyToken(String userId, String token, List<String> serverIPs, List<Integer> ports); ErrorCode verifyToken(String userId, String token, List<String> serverIPs, List<Integer> ports);
@@ -180,13 +179,14 @@ public interface IMessagesStore {
void clearUserFriend(String userId); void clearUserFriend(String userId);
List<WFCMessage.FriendRequest> getFriendRequestList(String userId, long version); List<WFCMessage.FriendRequest> getFriendRequestList(String userId, long version);
ErrorCode saveAddFriendRequest(String userId, WFCMessage.AddFriendRequest request, long[] head, boolean isAdmin); ErrorCode saveAddFriendRequest(String userId, WFCMessage.AddFriendRequest request, long[] head, boolean isAdmin, boolean isRobot);
ErrorCode handleFriendRequest(String userId, WFCMessage.HandleFriendRequest request, WFCMessage.Message.Builder msgBuilder, long[] heads, boolean isAdmin); ErrorCode handleFriendRequest(String userId, WFCMessage.HandleFriendRequest request, WFCMessage.Message.Builder msgBuilder, long[] heads, boolean isAdmin);
ErrorCode deleteFriend(String userId, String friendUid, long[] head); ErrorCode deleteFriend(String userId, String friendUid, long[] head);
ErrorCode blackUserRequest(String fromUser, String targetUserId, int status, long[] head); ErrorCode blackUserRequest(String fromUser, String targetUserId, int status, long[] head);
FriendData getFriendData(String fromUser, String targetUserId); FriendData getFriendData(String fromUser, String targetUserId);
ErrorCode SyncFriendRequestUnread(String userId, long unreadDt, long[] head); ErrorCode SyncFriendRequestUnread(String userId, long unreadDt, long[] head);
ErrorCode isAllowUserMessage(String fromUser, String userId); ErrorCode isAllowUserMessage(String fromUser, String userId, int line);
ErrorCode isBlacked(String fromUser, String userId);
ErrorCode setFriendAliasRequest(String fromUser, String targetUserId, String alias, long[] head); ErrorCode setFriendAliasRequest(String fromUser, String targetUserId, String alias, long[] head);
ErrorCode setFriendExtraRequest(String fromUser, String targetUserId, String extra, long[] head); ErrorCode setFriendExtraRequest(String fromUser, String targetUserId, String extra, long[] head);
@@ -225,6 +225,9 @@ public interface IMessagesStore {
boolean checkUserInChannel(String user, String channelId); boolean checkUserInChannel(String user, String channelId);
Collection<String> getChannelSubscriber(String channelId); Collection<String> getChannelSubscriber(String channelId);
int getOnlineUserCount();
GetOnlineUserResult getOnlineUsers(int offset, int count);
Set<String> handleSensitiveWord(String message); Set<String> handleSensitiveWord(String message);
boolean addSensitiveWords(List<String> words); boolean addSensitiveWords(List<String> words);
boolean removeSensitiveWords(List<String> words); boolean removeSensitiveWords(List<String> words);
@@ -241,9 +244,13 @@ public interface IMessagesStore {
boolean isForwardMessageWithClientInfo(); boolean isForwardMessageWithClientInfo();
boolean isRobotCallbackWithClientInfo(); boolean isRobotCallbackWithClientInfo();
boolean isChannelCallbackWithClientInfo(); boolean isChannelCallbackWithClientInfo();
boolean isChannelNewCallbackFeature();
boolean isRobotAutoAcceptFriendRequest(); boolean isRobotAutoAcceptFriendRequest();
long getPushExpiredTimes();
Set<Integer> getForcePushTypes();
List<Integer> getClientForbiddenSendTypes(); List<Integer> getClientForbiddenSendTypes();
List<Integer> getBlackListExceptionTypes(); List<Integer> getBlackListExceptionTypes();
List<Integer> getGroupMuteExceptionTypes(); List<Integer> getGroupMuteExceptionTypes();
@@ -74,6 +74,8 @@ public interface ISessionsStore {
*/ */
Collection<ClientSession> getAllSessions(); Collection<ClientSession> getAllSessions();
boolean isClientOnline(String clientId);
StoredMessage inFlightAck(String clientID, int messageID); StoredMessage inFlightAck(String clientID, int messageID);
/** /**
@@ -21,7 +21,6 @@ import cn.wildfirechat.pojos.OutputMessageData;
import cn.wildfirechat.proto.ProtoConstants; import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage; import cn.wildfirechat.proto.WFCMessage;
import cn.wildfirechat.push.PushServer; import cn.wildfirechat.push.PushServer;
import com.google.gson.Gson;
import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.util.StringUtil; import com.hazelcast.util.StringUtil;
import cn.wildfirechat.pojos.OutputNotifyChannelSubscribeStatus; import cn.wildfirechat.pojos.OutputNotifyChannelSubscribeStatus;
@@ -223,7 +222,12 @@ public class MessagesPublisher {
if (targetSession.getPlatform() == ProtoConstants.Platform.Platform_WEB if (targetSession.getPlatform() == ProtoConstants.Platform.Platform_WEB
|| targetSession.getPlatform() == ProtoConstants.Platform.Platform_Windows || targetSession.getPlatform() == ProtoConstants.Platform.Platform_Windows
|| targetSession.getPlatform() == ProtoConstants.Platform.Platform_LINUX || targetSession.getPlatform() == ProtoConstants.Platform.Platform_LINUX
|| targetSession.getPlatform() == ProtoConstants.Platform.Platform_OSX) { || targetSession.getPlatform() == ProtoConstants.Platform.Platform_OSX
|| targetSession.getPlatform() == ProtoConstants.Platform.Platform_HarmonyPC
|| targetSession.getPlatform() == ProtoConstants.Platform.Platform_iPad
|| targetSession.getPlatform() == ProtoConstants.Platform.Platform_APad
|| targetSession.getPlatform() == ProtoConstants.Platform.Platform_HarmonyPad
) {
boolean targetIsActive = this.connectionDescriptors.isConnected(targetSession.getClientSession().clientID); boolean targetIsActive = this.connectionDescriptors.isConnected(targetSession.getClientSession().clientID);
if (targetIsActive) { if (targetIsActive) {
isPcOnline = true; isPcOnline = true;
@@ -235,7 +239,7 @@ public class MessagesPublisher {
for (Session targetSession : sessions) { for (Session targetSession : sessions) {
//超过7天不活跃的用户忽略 //超过7天不活跃的用户忽略
if(System.currentTimeMillis() - targetSession.getLastActiveTime() > 7 * 24 * 60 * 60 * 1000) { if(System.currentTimeMillis() - targetSession.getLastActiveTime() > m_messagesStore.getPushExpiredTimes()) {
continue; continue;
} }
@@ -266,6 +270,7 @@ public class MessagesPublisher {
boolean isVoipSilent; boolean isVoipSilent;
boolean isNoDisturb; boolean isNoDisturb;
boolean isConvSilent = false; boolean isConvSilent = false;
boolean isForcePush = false;
if (pullType == ProtoConstants.PullType.Pull_ChatRoom) { if (pullType == ProtoConstants.PullType.Pull_ChatRoom) {
isSilent = true; isSilent = true;
isConvSilent = true; isConvSilent = true;
@@ -284,6 +289,11 @@ public class MessagesPublisher {
conversation = WFCMessage.Conversation.newBuilder().setType(conversationType).setLine(line).setTarget(target).build(); conversation = WFCMessage.Conversation.newBuilder().setType(conversationType).setLine(line).setTarget(target).build();
} }
if(m_messagesStore.getForcePushTypes().contains(messageContentType)) {
LOG.info("The message type {} force push", messageContentType);
isForcePush = true;
}
if (m_messagesStore.getUserConversationSilent(user, conversation)) { if (m_messagesStore.getUserConversationSilent(user, conversation)) {
LOG.info("The conversation {}-{}-{} is slient", conversation.getType(), conversation.getTarget(), conversation.getLine()); LOG.info("The conversation {}-{}-{} is slient", conversation.getType(), conversation.getTarget(), conversation.getLine());
isConvSilent = true; isConvSilent = true;
@@ -364,17 +374,17 @@ public class MessagesPublisher {
continue; continue;
} }
if (isConvSilent && !isVoip) { if (isConvSilent && !isVoip && !isForcePush) {
LOG.info("Silent of user or conversation"); LOG.info("Silent of user or conversation");
continue; continue;
} }
if (isSilent && !isVoip) { if (isSilent && !isVoip && !isForcePush) {
LOG.info("Silent of user"); LOG.info("Silent of user");
continue; continue;
} }
if(isVoip && isVoipSilent) { if(isVoip && isVoipSilent && !isForcePush) {
LOG.info("voip silent of user"); LOG.info("voip silent of user");
continue; continue;
} }
@@ -441,6 +451,7 @@ public class MessagesPublisher {
WFCMessage.Message message = m_messagesStore.getMessage(messageHead); WFCMessage.Message message = m_messagesStore.getMessage(messageHead);
if (message != null) { if (message != null) {
message = message.toBuilder().setMessageId(0).build();
for (String user : receivers) { for (String user : receivers) {
Collection<Session> sessions = m_sessionsStore.sessionForUser(user); Collection<Session> sessions = m_sessionsStore.sessionForUser(user);
@@ -469,6 +480,33 @@ public class MessagesPublisher {
LOG.info("the target {} of user {} is not active", targetSession.getClientID(), targetSession.getUsername()); LOG.info("the target {} of user {} is not active", targetSession.getClientID(), targetSession.getUsername());
} }
} }
if(sessions.isEmpty() && message.getContent().getType() == 403 && !user.equals(message.getFromUser())) {
WFCMessage.User userInfo = m_messagesStore.getUserInfo(user);
if (userInfo != null && userInfo.getType() == ProtoConstants.UserType.UserType_Robot) {
WFCMessage.Robot robot = m_messagesStore.getRobot(user);
if (robot != null && !StringUtil.isNullOrEmpty(robot.getCallback())) {
OutputClient outputClient = null;
if(m_messagesStore.isRobotCallbackWithClientInfo() && !StringUtil.isNullOrEmpty(exceptClientId)) {
Session session = m_sessionsStore.getSession(exceptClientId);
if(session != null && session.getUsername().equals(message.getFromUser())) {
outputClient = new OutputClient(session.getPlatform(), exceptClientId);
}
}
final WFCMessage.Message finalMsg = message;
OutputClient finalOutputClient = outputClient;
Server.getServer().getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(robot.getCallback(), GsonUtil.gson.toJson(OutputMessageData.fromProtoMessage(finalMsg, finalOutputClient), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Robot_Message_Callback);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
}
});
}
}
}
} }
} }
} }
@@ -631,7 +669,15 @@ public class MessagesPublisher {
public void publish2Receivers(WFCMessage.Message message, Set<String> receivers, String exceptClientId, int pullType) { public void publish2Receivers(WFCMessage.Message message, Set<String> receivers, String exceptClientId, int pullType) {
if (message.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Channel) { if (message.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Channel) {
WFCMessage.ChannelInfo channelInfo = m_messagesStore.getChannelInfo(message.getConversation().getTarget()); WFCMessage.ChannelInfo channelInfo = m_messagesStore.getChannelInfo(message.getConversation().getTarget());
if (channelInfo != null && !StringUtil.isNullOrEmpty(channelInfo.getCallback()) && channelInfo.getAutomatic() == 1 && !message.getFromUser().equals(channelInfo.getOwner())) {
boolean forwardMsg;
if(m_messagesStore.isChannelNewCallbackFeature()) {
forwardMsg = channelInfo != null && !StringUtil.isNullOrEmpty(channelInfo.getCallback()) && !StringUtil.isNullOrEmpty(exceptClientId);
} else {
forwardMsg = channelInfo != null && !StringUtil.isNullOrEmpty(channelInfo.getCallback()) && channelInfo.getAutomatic() == 1 && !message.getFromUser().equals(channelInfo.getOwner());
}
if (forwardMsg) {
OutputClient outputClient = null; OutputClient outputClient = null;
if(m_messagesStore.isChannelCallbackWithClientInfo() && !StringUtil.isNullOrEmpty(exceptClientId)) { if(m_messagesStore.isChannelCallbackWithClientInfo() && !StringUtil.isNullOrEmpty(exceptClientId)) {
Session session = m_sessionsStore.getSession(exceptClientId); Session session = m_sessionsStore.getSession(exceptClientId);
@@ -730,7 +776,10 @@ public class MessagesPublisher {
} }
public void notifyChannelListenStatusChanged(WFCMessage.ChannelInfo channelInfo, String user, boolean listen) { public void notifyChannelListenStatusChanged(WFCMessage.ChannelInfo channelInfo, String user, boolean listen) {
if (channelInfo == null || StringUtil.isNullOrEmpty(channelInfo.getCallback()) || channelInfo.getAutomatic() == 0) { if (channelInfo == null || StringUtil.isNullOrEmpty(channelInfo.getCallback())) {
return;
}
if(!m_messagesStore.isChannelNewCallbackFeature() && channelInfo.getAutomatic() == 0) {
return; return;
} }
@@ -17,6 +17,7 @@
package io.moquette.spi.impl; package io.moquette.spi.impl;
import cn.wildfirechat.common.ErrorCode; import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.OutputCheckUserOnline;
import cn.wildfirechat.pojos.UserOnlineStatus; import cn.wildfirechat.pojos.UserOnlineStatus;
import cn.wildfirechat.proto.ProtoConstants; import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage; import cn.wildfirechat.proto.WFCMessage;
@@ -266,7 +267,27 @@ public class ProtocolProcessor {
if (!StringUtil.isNullOrEmpty(mUserOnlineStatusCallback)) { if (!StringUtil.isNullOrEmpty(mUserOnlineStatusCallback)) {
mServer.getCallbackScheduler().execute(() -> { mServer.getCallbackScheduler().execute(() -> {
try { try {
HttpUtils.httpJsonPost(mUserOnlineStatusCallback, GsonUtil.gson.toJson(new UserOnlineStatus(userId, clientId, platform, status, packageName)), HttpUtils.HttpPostType.POST_TYPE_User_Online_Event_Callback); int sessionstatus;
Collection<MemorySessionStore.Session> useSessions = m_sessionsStore.sessionForUser(userId);
UserOnlineStatus userOnlineStatus = new UserOnlineStatus(userId, clientId, platform, status, packageName);
userOnlineStatus.sessions = new ArrayList<>();
for (MemorySessionStore.Session session : useSessions) {
if (session.getDeleted() > 0) {
continue;
}
ConnectionDescriptor descriptor = connectionDescriptors.getConnection(session.getClientID());
if (descriptor == null) {
sessionstatus = 1;
} else {
sessionstatus = 0;
}
userOnlineStatus.sessions.add(new OutputCheckUserOnline.Session(userId, session.getClientID(), session.getPlatform(), sessionstatus, session.getLastActiveTime(), session.getAppName()));
}
HttpUtils.httpJsonPost(mUserOnlineStatusCallback, GsonUtil.gson.toJson(userOnlineStatus), HttpUtils.HttpPostType.POST_TYPE_User_Online_Event_Callback);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception); Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
@@ -731,6 +752,10 @@ public class ProtocolProcessor {
channel.flush(); channel.flush();
} }
public ConnectionDescriptorStore getConnectionDescriptors() {
return connectionDescriptors;
}
public void addInterceptHandler(InterceptHandler interceptHandler) { public void addInterceptHandler(InterceptHandler interceptHandler) {
this.m_interceptor.addInterceptHandler(interceptHandler); this.m_interceptor.addInterceptHandler(interceptHandler);
} }
@@ -26,6 +26,7 @@ import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPOutputStream;
import cn.hutool.core.util.ReflectUtil;
import cn.wildfirechat.proto.ProtoConstants; import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.server.ThreadPoolExecutorWrapper; import cn.wildfirechat.server.ThreadPoolExecutorWrapper;
import com.google.gson.Gson; import com.google.gson.Gson;
@@ -92,7 +93,7 @@ public class Qos1PublishHandler extends QosPublishHandler {
for (Class cls:ClassUtil.getAllAssignedClass(IMHandler.class)) { for (Class cls:ClassUtil.getAllAssignedClass(IMHandler.class)) {
Handler annotation = (Handler)cls.getAnnotation(Handler.class); Handler annotation = (Handler)cls.getAnnotation(Handler.class);
if(annotation != null) { if(annotation != null) {
IMHandler handler = (IMHandler) com.xiaoleilu.hutool.util.ClassUtil.newInstance(cls); IMHandler handler = (IMHandler) ReflectUtil.newInstance(cls);
m_imHandlers.put(annotation.value(), handler); m_imHandlers.put(annotation.value(), handler);
} }
} }
@@ -140,7 +141,7 @@ public class Qos1PublishHandler extends QosPublishHandler {
status = 0; status = 0;
} }
out.addSession(userId, session.getClientID(), session.getPlatform(), status, session.getLastActiveTime()); out.addSession(userId, session.getClientID(), session.getPlatform(), status, session.getLastActiveTime(), session.getAppName());
} }
callback.onRouteHandled(GsonUtil.gson.toJson(out).getBytes()); callback.onRouteHandled(GsonUtil.gson.toJson(out).getBytes());
@@ -116,6 +116,27 @@ public class DBUtil {
} else if(flyway.info().current().getVersion().getMajor().intValue() < 43) { } else if(flyway.info().current().getVersion().getMajor().intValue() < 43) {
System.out.println("数据库执行升级需要较长时间,可能长达数分钟或更长,请耐心等待,不要中断。。。"); System.out.println("数据库执行升级需要较长时间,可能长达数分钟或更长,请耐心等待,不要中断。。。");
} }
if(flyway.info().current() != null && flyway.info().current().getVersion().getMajor().intValue() < 55) {
Connection connection = null;
PreparedStatement statement = null;
try {
connection = getConnection();
String sql = "update flyway_schema_history set checksum = ? where version = ? and checksum = ?";
statement = connection.prepareStatement(sql);
int index = 1;
statement.setLong(index++, -931486413L);
statement.setString(index++, "3");
statement.setLong(index++, 478454046L);
statement.executeUpdate();
} catch (SQLException e) {
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
}
} }
flyway.migrate(); flyway.migrate();
@@ -102,7 +102,7 @@ public class HttpUtils {
if(httpCallback != null) { if(httpCallback != null) {
int code = response.code(); int code = response.code();
if(code == 200) { if(code == 200) {
if(response.body() != null && response.body().contentLength() > 0) { if(response.body() != null) {
httpCallback.onSuccess(response.body().string()); httpCallback.onSuccess(response.body().string());
} else { } else {
httpCallback.onSuccess(null); httpCallback.onSuccess(null);
@@ -20,4 +20,5 @@ public interface UserSettingScope {
int kUserSettingPttSilent = 25; int kUserSettingPttSilent = 25;
int kUserSettingGroupRemark = 26; int kUserSettingGroupRemark = 26;
int kUserSettingPrivacySearchable = 27; int kUserSettingPrivacySearchable = 27;
int kUserSettingAddFriendStrategy = 28;
} }
+1 -1
View File
@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>wildfirechat-parent</artifactId> <artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId> <groupId>cn.wildfirechat</groupId>
<version>1.1.8</version> <version>1.3.2</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@@ -5,6 +5,7 @@ public interface APIPath {
String Chatroom_Destroy = "/admin/chatroom/del"; String Chatroom_Destroy = "/admin/chatroom/del";
String Chatroom_Info = "/admin/chatroom/info"; String Chatroom_Info = "/admin/chatroom/info";
String Chatroom_GetMembers = "/admin/chatroom/members"; String Chatroom_GetMembers = "/admin/chatroom/members";
String Chatroom_GetUserChatroom = "/admin/chatroom/user_chatroom";
String Chatroom_SetBlacklist = "/admin/chatroom/set_black_status"; String Chatroom_SetBlacklist = "/admin/chatroom/set_black_status";
String Chatroom_GetBlacklist = "/admin/chatroom/get_black_status"; String Chatroom_GetBlacklist = "/admin/chatroom/get_black_status";
String Chatroom_SetManager = "/admin/chatroom/set_manager"; String Chatroom_SetManager = "/admin/chatroom/set_manager";
@@ -16,9 +17,15 @@ public interface APIPath {
String Sensitive_Del = "/admin/sensitive/del"; String Sensitive_Del = "/admin/sensitive/del";
String Sensitive_Query = "/admin/sensitive/query"; String Sensitive_Query = "/admin/sensitive/query";
String Create_Domain = "/admin/domain/create";
String Get_Domain = "/admin/domain/get";
String Destroy_Domain = "/admin/domain/destroy";
String List_Domain = "/admin/domain/list";
String Create_User = "/admin/user/create"; String Create_User = "/admin/user/create";
String Update_User = "/admin/user/update"; String Update_User = "/admin/user/update";
String Destroy_User = "/admin/user/destroy"; String Destroy_User = "/admin/user/destroy";
String Search_User = "/admin/user/search_user";
String Create_Robot = "/admin/robot/create"; String Create_Robot = "/admin/robot/create";
String CreateOrUpdate_Device = "/admin/device/create"; String CreateOrUpdate_Device = "/admin/device/create";
String Get_Device = "/admin/device/get"; String Get_Device = "/admin/device/get";
@@ -26,6 +33,8 @@ public interface APIPath {
String User_Get_Token = "/admin/user/get_token"; String User_Get_Token = "/admin/user/get_token";
String User_Update_Block_Status = "/admin/user/update_block_status"; String User_Update_Block_Status = "/admin/user/update_block_status";
String User_Get_Info = "/admin/user/get_info"; String User_Get_Info = "/admin/user/get_info";
String User_Batch_Get_Infos = "/admin/user/batch_get_infos";
String User_Get_Email_Info = "/admin/user/get_info_by_email";
String User_Get_All = "/admin/user/all"; String User_Get_All = "/admin/user/all";
String User_Get_Robot_Info = "/admin/user/get_robot_info"; String User_Get_Robot_Info = "/admin/user/get_robot_info";
String User_Get_Blocked_List = "/admin/user/get_blocked_list"; String User_Get_Blocked_List = "/admin/user/get_blocked_list";
@@ -36,6 +45,7 @@ public interface APIPath {
String User_Kickoff_Client = "/admin/user/kickoff_client"; String User_Kickoff_Client = "/admin/user/kickoff_client";
String User_Online_Count = "/admin/user/online_count"; String User_Online_Count = "/admin/user/online_count";
String User_Online_List = "/admin/user/online_list"; String User_Online_List = "/admin/user/online_list";
String User_Session_List = "/admin/user/session_list";
String User_Application_Get_UserInfo = "/admin/user/app_get_user_info"; String User_Application_Get_UserInfo = "/admin/user/app_get_user_info";
String Friend_Update_Status = "/admin/friend/status"; String Friend_Update_Status = "/admin/friend/status";
@@ -49,7 +59,10 @@ public interface APIPath {
String Friend_Get_Requests = "/admin/friend/get_requests"; String Friend_Get_Requests = "/admin/friend/get_requests";
String Relation_Get = "/admin/relation/get"; String Relation_Get = "/admin/relation/get";
String Handle_Friend_Send_Request = "/admin/friend/handle_send_request";
String Msg_Send = "/admin/message/send"; String Msg_Send = "/admin/message/send";
String Msg_Publish = "/admin/message/publish";
String Msg_Recall = "/admin/message/recall"; String Msg_Recall = "/admin/message/recall";
String Msg_Delete = "/admin/message/delete"; String Msg_Delete = "/admin/message/delete";
String Msg_Update = "/admin/message/update"; String Msg_Update = "/admin/message/update";
@@ -58,6 +71,8 @@ public interface APIPath {
String Msg_Multicast = "/admin/message/multicast"; String Msg_Multicast = "/admin/message/multicast";
String Msg_RecallBroadCast = "/admin/message/recall_broadcast"; String Msg_RecallBroadCast = "/admin/message/recall_broadcast";
String Msg_RecallMultiCast = "/admin/message/recall_multicast"; String Msg_RecallMultiCast = "/admin/message/recall_multicast";
String Msg_DeleteBroadCast = "/admin/message/delete_broadcast";
String Msg_DeleteMultiCast = "/admin/message/delete_multicast";
String Msg_ConvRead = "/admin/message/conv_read"; String Msg_ConvRead = "/admin/message/conv_read";
String Msg_Delivery = "/admin/message/delivery"; String Msg_Delivery = "/admin/message/delivery";
String Conversation_Delete = "/admin/conversation/delete"; String Conversation_Delete = "/admin/conversation/delete";
@@ -67,6 +82,7 @@ public interface APIPath {
String Group_Dismiss = "/admin/group/del"; String Group_Dismiss = "/admin/group/del";
String Group_Transfer = "/admin/group/transfer"; String Group_Transfer = "/admin/group/transfer";
String Group_Get_Info = "/admin/group/get_info"; String Group_Get_Info = "/admin/group/get_info";
String Group_Batch_Info = "/admin/group/batch_infos";
String Group_Modify_Info = "/admin/group/modify"; String Group_Modify_Info = "/admin/group/modify";
String Group_Member_List = "/admin/group/member/list"; String Group_Member_List = "/admin/group/member/list";
String Group_Member_Get = "/admin/group/member/get"; String Group_Member_Get = "/admin/group/member/get";
@@ -77,10 +93,15 @@ public interface APIPath {
String Group_Mute_Member = "/admin/group/manager/mute"; String Group_Mute_Member = "/admin/group/manager/mute";
String Group_Allow_Member = "/admin/group/manager/allow"; String Group_Allow_Member = "/admin/group/manager/allow";
String Get_User_Groups = "/admin/group/of_user"; String Get_User_Groups = "/admin/group/of_user";
String Get_User_Groups_By_Type = "/admin/group/of_user_by_type";
String Group_Set_Member_Alias = "/admin/group/member/set_alias"; String Group_Set_Member_Alias = "/admin/group/member/set_alias";
String Group_Set_Member_Extra = "/admin/group/member/set_extra"; String Group_Set_Member_Extra = "/admin/group/member/set_extra";
String Get_Common_Groups = "/admin/group/common_group"; String Get_Common_Groups = "/admin/group/common_group";
String Sync_Group = "/admin/mesh/group_sync";
String Conference_User_Request = "/admin/conference/user_request";
String Conference_User_Event = "/admin/conference/user_event";
String Create_Channel = "/admin/channel/create"; String Create_Channel = "/admin/channel/create";
String Destroy_Channel = "/admin/channel/destroy"; String Destroy_Channel = "/admin/channel/destroy";
String Get_Channel_Info = "/admin/channel/get"; String Get_Channel_Info = "/admin/channel/get";
@@ -88,7 +109,7 @@ public interface APIPath {
String Check_User_Subscribe_Channel = "/admin/channel/is_subscribed"; String Check_User_Subscribe_Channel = "/admin/channel/is_subscribed";
String Get_System_Setting = "/admin/system/get_setting"; String Get_System_Setting = "/admin/system/get_setting";
String Put_System_Setting = "/admin/system/put_setting"; String Put_System_Setting = "/admin/system/put_setting";
String GET_CUSTOMER = "/admin/customer";
String Health = "/admin/health"; String Health = "/admin/health";
String Conference_List = "/admin/conference/list"; String Conference_List = "/admin/conference/list";
@@ -113,6 +134,8 @@ public interface APIPath {
String Robot_User_Info = "/robot/user_info"; String Robot_User_Info = "/robot/user_info";
String Robot_Get_Profile = "/robot/profile"; String Robot_Get_Profile = "/robot/profile";
String Robot_Message_Send = "/robot/message/send"; String Robot_Message_Send = "/robot/message/send";
String Robot_Message_Recall = "/robot/message/recall";
String Robot_Message_Update = "/robot/message/update";
String Robot_Set_Callback = "/robot/set_callback"; String Robot_Set_Callback = "/robot/set_callback";
String Robot_Get_Callback = "/robot/get_callback"; String Robot_Get_Callback = "/robot/get_callback";
String Robot_Delete_Callback = "/robot/delete_callback"; String Robot_Delete_Callback = "/robot/delete_callback";
@@ -133,4 +156,18 @@ public interface APIPath {
String Robot_Group_Member_Quit = "/robot/group/member/quit"; String Robot_Group_Member_Quit = "/robot/group/member/quit";
String Robot_Group_Transfer = "/robot/group/transfer"; String Robot_Group_Transfer = "/robot/group/transfer";
String Robot_Group_Set_Manager = "/robot/group/manager/set"; String Robot_Group_Set_Manager = "/robot/group/manager/set";
String Robot_Moments_Post_Feed = "/robot/moments/feed/post";
String Robot_Moments_Pull_Feeds = "/robot/moments/feed/pull";
String Robot_Moments_Update_Feed = "/robot/moments/feed/update";
String Robot_Moments_Post_Comment = "/robot/moments/comment/post";
String Robot_Moments_Pull_Comment = "/robot/moments/comment/pull";
String Robot_Moments_Fetch_Feed = "/robot/moments/feed/pull_one";
String Robot_Moments_Fetch_Profiles = "/robot/moments/profiles/pull";
String Robot_Moments_Recall_Comment = "/robot/moments/comment/recall";
String Robot_Moments_Recall_Feed = "/robot/moments/feed/recall";
String Robot_Moments_Update_Profiles_List_Value = "/robot/moments/profiles/list/push";
String Robot_Moments_Update_Profiles_Value = "/robot/moments/profiles/value/push";
String Robot_Conference_Request = "/robot/conference/request";
} }
@@ -66,6 +66,8 @@ public enum ErrorCode {
ERROR_CODE_FUNCTION_DISABLED(220, "function disabled"), ERROR_CODE_FUNCTION_DISABLED(220, "function disabled"),
ERROR_CODE_OTHER_CLIENT_ALREADY_IN_CHATROOM(225, "other client already in chatroom"),
ERROR_CODE_CHANNEL_NO_EXIST(236, "channel no exist"), ERROR_CODE_CHANNEL_NO_EXIST(236, "channel no exist"),
ERROR_CODE_CHANNEL_NO_SECRET(237, "channel no secret"), ERROR_CODE_CHANNEL_NO_SECRET(237, "channel no secret"),
ERROR_CODE_USER_NOT_PREPARED(238, "user not prepared"), ERROR_CODE_USER_NOT_PREPARED(238, "user not prepared"),
@@ -1,19 +0,0 @@
package cn.wildfirechat.messagecontentbuilder;
import cn.wildfirechat.pojos.MessagePayload;
abstract public class MediaMessageContentBuilder extends MessageContentBuilder{
private String remoteMediaUrl;
public MediaMessageContentBuilder remoteMediaUrl(String remoteMediaUrl) {
this.remoteMediaUrl = remoteMediaUrl;
return this;
}
@Override
protected MessagePayload encodeBase() {
MessagePayload payload = super.encodeBase();
payload.setRemoteMediaUrl(remoteMediaUrl);
return payload;
}
}
@@ -1,33 +0,0 @@
package cn.wildfirechat.messagecontentbuilder;
import cn.wildfirechat.pojos.MessagePayload;
import java.util.List;
public abstract class MessageContentBuilder {
private int mentionedType;
private List<String> mentionedTargets;
private String extra;
public MessageContentBuilder mentionedType(int mentionedType) {
this.mentionedType = mentionedType;
return this;
}
public MessageContentBuilder mentionedTargets(List<String> mentionedTargets) {
this.mentionedTargets = mentionedTargets;
return this;
}
public MessageContentBuilder extra(String extra) {
this.extra = extra;
return this;
}
protected MessagePayload encodeBase() {
MessagePayload payload = new MessagePayload();
payload.setMentionedType(mentionedType);
payload.setMentionedTarget(mentionedTargets);
payload.setExtra(extra);
return payload;
}
abstract public MessagePayload build();
}
@@ -1,25 +0,0 @@
package cn.wildfirechat.messagecontentbuilder;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import org.json.simple.JSONObject;
public class SoundMessageContentBuilder extends MediaMessageContentBuilder {
private int duration;
public static SoundMessageContentBuilder newBuilder(int duration) {
SoundMessageContentBuilder builder = new SoundMessageContentBuilder();
builder.duration = duration;
return builder;
}
@Override
public MessagePayload build() {
MessagePayload payload = encodeBase();
payload.setType(ProtoConstants.ContentType.Voice);
payload.setMediaType(ProtoConstants.MessageMediaType.VOICE);
payload.setPersistFlag(ProtoConstants.PersistFlag.Persist_And_Count);
JSONObject jsonObject = new JSONObject();
jsonObject.put("duration", duration);
payload.setContent(jsonObject.toJSONString());
return payload;
}
}
@@ -1,21 +0,0 @@
package cn.wildfirechat.messagecontentbuilder;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
public class TextMessageContentBuilder extends MessageContentBuilder{
private String text;
public static TextMessageContentBuilder newBuilder(String text) {
TextMessageContentBuilder builder = new TextMessageContentBuilder();
builder.text = text;
return builder;
}
@Override
public MessagePayload build() {
MessagePayload payload = encodeBase();
payload.setType(ProtoConstants.ContentType.Text);
payload.setPersistFlag(ProtoConstants.PersistFlag.Persist_And_Count);
payload.setSearchableContent(text);
return payload;
}
}
@@ -10,4 +10,9 @@ public class ConferenceCreateEvent {
public int bitrate; public int bitrate;
public boolean advance; public boolean advance;
public boolean recording; public boolean recording;
public long timestamp;
public ConferenceCreateEvent() {
timestamp = System.currentTimeMillis();
}
} }
@@ -3,4 +3,9 @@ package cn.wildfirechat.pojos;
public class ConferenceDestroyEvent { public class ConferenceDestroyEvent {
public String userId; public String userId;
public String roomId; public String roomId;
public long timestamp;
public ConferenceDestroyEvent() {
timestamp = System.currentTimeMillis();
}
} }
@@ -4,4 +4,9 @@ public class ConferenceJoinEvent {
public String userId; public String userId;
public String roomId; public String roomId;
public boolean screenSharing; public boolean screenSharing;
public long timestamp;
public ConferenceJoinEvent() {
timestamp = System.currentTimeMillis();
}
} }
@@ -6,4 +6,9 @@ public class ConferenceLeaveEvent {
public boolean rejoin; public boolean rejoin;
public boolean kicked; public boolean kicked;
public boolean screenSharing; public boolean screenSharing;
public long timestamp;
public ConferenceLeaveEvent() {
timestamp = System.currentTimeMillis();
}
} }
@@ -5,4 +5,9 @@ public class ConferencePublishEvent {
public boolean video; public boolean video;
public String roomId; public String roomId;
public boolean screenSharing; public boolean screenSharing;
public long timestamp;
public ConferencePublishEvent() {
timestamp = System.currentTimeMillis();
}
} }
@@ -4,4 +4,9 @@ public class ConferenceUnpublishEvent {
public String userId; public String userId;
public String roomId; public String roomId;
public boolean screenSharing; public boolean screenSharing;
public long timestamp;
public ConferenceUnpublishEvent() {
timestamp = System.currentTimeMillis();
}
} }
@@ -0,0 +1,37 @@
package cn.wildfirechat.pojos;
import java.util.ArrayList;
import java.util.List;
public class GetUserSessionResult {
public static class UserSession {
public String userId;
public String clientId;
public int platform;
public int pushType;
public String deviceToken;
public String deviceVoipToken;
boolean isOnline;
public UserSession() {
}
public UserSession(String userId, String clientId, int platform, int pushType, String deviceToken, String deviceVoipToken, boolean isOnline) {
this.userId = userId;
this.clientId = clientId;
this.platform = platform;
this.pushType = pushType;
this.deviceToken = deviceToken;
this.deviceVoipToken = deviceVoipToken;
this.isOnline = isOnline;
}
}
public List<UserSession> userSessions;
public GetUserSessionResult() {
userSessions = new ArrayList<>();
}
}
@@ -13,6 +13,7 @@ import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
import io.netty.util.internal.StringUtil;
import java.util.List; import java.util.List;
@@ -32,6 +33,8 @@ public class GroupNotificationBinaryContent {
//value2(member or something) //value2(member or something)
private String m; private String m;
private String extra;
public GroupNotificationBinaryContent() { public GroupNotificationBinaryContent() {
} }
@@ -89,8 +92,18 @@ public class GroupNotificationBinaryContent {
this.ms = ms; this.ms = ms;
} }
public GroupNotificationBinaryContent setExtra(String extra) {
this.extra = extra;
return this;
}
public WFCMessage.MessageContent getGroupNotifyContent(int groupContentType) { public WFCMessage.MessageContent getGroupNotifyContent(int groupContentType) {
return WFCMessage.MessageContent.newBuilder().setType(groupContentType).setData(ByteString.copyFromUtf8(new GsonBuilder().disableHtmlEscaping().create().toJson(this))).build(); WFCMessage.MessageContent.Builder builder = WFCMessage.MessageContent.newBuilder().setType(groupContentType).setData(ByteString.copyFromUtf8(new GsonBuilder().disableHtmlEscaping().create().toJson(this)));
if(!StringUtil.isNullOrEmpty(extra)) {
builder.setExtra(extra);
}
return builder.build();
} }
public WFCMessage.MessageContent getAddGroupNotifyContent() { public WFCMessage.MessageContent getAddGroupNotifyContent() {
@@ -4,4 +4,5 @@ public class GroupUpdateEvent {
public String operatorId; public String operatorId;
public String groupId; public String groupId;
public int type; public int type;
public PojoGroupInfo groupInfo;
} }
@@ -17,6 +17,7 @@ import java.util.List;
public class InputAddGroupMember extends InputGroupBase { public class InputAddGroupMember extends InputGroupBase {
private String group_id; private String group_id;
private List<PojoGroupMember> members; private List<PojoGroupMember> members;
private String member_extra;
public String getGroup_id() { public String getGroup_id() {
return group_id; return group_id;
@@ -34,6 +35,14 @@ public class InputAddGroupMember extends InputGroupBase {
this.members = members; this.members = members;
} }
public String getMember_extra() {
return member_extra;
}
public void setMemberExtra(String extra) {
this.member_extra = extra;
}
public boolean isValide() { public boolean isValide() {
return true; return true;
} }
@@ -41,6 +50,9 @@ public class InputAddGroupMember extends InputGroupBase {
public WFCMessage.AddGroupMemberRequest toProtoGroupRequest() { public WFCMessage.AddGroupMemberRequest toProtoGroupRequest() {
WFCMessage.AddGroupMemberRequest.Builder addGroupBuilder = WFCMessage.AddGroupMemberRequest.newBuilder(); WFCMessage.AddGroupMemberRequest.Builder addGroupBuilder = WFCMessage.AddGroupMemberRequest.newBuilder();
addGroupBuilder.setGroupId(group_id); addGroupBuilder.setGroupId(group_id);
if(!StringUtil.isNullOrEmpty(member_extra)) {
addGroupBuilder.setExtra(member_extra);
}
for (PojoGroupMember pojoGroupMember : getMembers()) { for (PojoGroupMember pojoGroupMember : getMembers()) {
WFCMessage.GroupMember.Builder groupMemberBuilder = WFCMessage.GroupMember.newBuilder().setMemberId(pojoGroupMember.getMember_id()); WFCMessage.GroupMember.Builder groupMemberBuilder = WFCMessage.GroupMember.newBuilder().setMemberId(pojoGroupMember.getMember_id());
if (!StringUtil.isNullOrEmpty(pojoGroupMember.getAlias())) { if (!StringUtil.isNullOrEmpty(pojoGroupMember.getAlias())) {
@@ -0,0 +1,32 @@
/*
* 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 InputConferenceRequest {
public String userId;
public String clientId;
public String request;
public long sessionId;
public String roomId;
public String data;
public boolean advance;
public InputConferenceRequest() {
}
public InputConferenceRequest(String userId, String clientId, String request, long sessionId, String roomId, String data, boolean advance) {
this.userId = userId;
this.clientId = clientId;
this.request = request;
this.sessionId = sessionId;
this.roomId = roomId;
this.data = data;
this.advance = advance;
}
}
@@ -16,9 +16,10 @@ import java.util.List;
public class InputCreateGroup extends InputGroupBase { public class InputCreateGroup extends InputGroupBase {
private PojoGroup group; private PojoGroup group;
private String member_extra;
public boolean isValide() { public boolean isValide() {
return true; return !StringUtil.isNullOrEmpty(operator) && group != null;
} }
public WFCMessage.CreateGroupRequest toProtoGroupRequest() { public WFCMessage.CreateGroupRequest toProtoGroupRequest() {
@@ -68,6 +69,7 @@ public class InputCreateGroup extends InputGroupBase {
if(group_info.isSuper_group()) { if(group_info.isSuper_group()) {
groupInfoBuilder.setSuperGroup(1); groupInfoBuilder.setSuperGroup(1);
} }
groupInfoBuilder.setDeleted(0);
groupBuilder.setGroupInfo(groupInfoBuilder); groupBuilder.setGroupInfo(groupInfoBuilder);
if(group.getMembers() != null) { if(group.getMembers() != null) {
@@ -86,6 +88,9 @@ public class InputCreateGroup extends InputGroupBase {
WFCMessage.CreateGroupRequest.Builder createGroupReqBuilder = WFCMessage.CreateGroupRequest.newBuilder(); WFCMessage.CreateGroupRequest.Builder createGroupReqBuilder = WFCMessage.CreateGroupRequest.newBuilder();
createGroupReqBuilder.setGroup(groupBuilder); createGroupReqBuilder.setGroup(groupBuilder);
if(!StringUtil.isNullOrEmpty(member_extra)) {
createGroupReqBuilder.setMemberExtra(member_extra);
}
if (to_lines != null) { if (to_lines != null) {
for (Integer line : to_lines for (Integer line : to_lines
) { ) {
@@ -106,4 +111,12 @@ public class InputCreateGroup extends InputGroupBase {
public void setGroup(PojoGroup group) { public void setGroup(PojoGroup group) {
this.group = group; this.group = group;
} }
public String getMember_extra() {
return member_extra;
}
public void setMember_extra(String member_extra) {
this.member_extra = member_extra;
}
} }
@@ -0,0 +1,40 @@
/*
* 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 InputGetUserGroupByType {
private String userId;
private List<Integer> groupMemberTypes;
public InputGetUserGroupByType() {
}
public InputGetUserGroupByType(String userId, List<Integer> groupMemberTypes) {
this.userId = userId;
this.groupMemberTypes = groupMemberTypes;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public List<Integer> getGroupMemberTypes() {
return groupMemberTypes;
}
public void setGroupMemberTypes(List<Integer> groupMemberTypes) {
this.groupMemberTypes = groupMemberTypes;
}
}
@@ -0,0 +1,35 @@
/*
* 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 InputGetUserSK {
private String uid;
private String cid;
public InputGetUserSK(String uid, String cid) {
this.uid = uid;
this.cid = cid;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getCid() {
return cid;
}
public void setCid(String cid) {
this.cid = cid;
}
}
@@ -15,6 +15,7 @@ public class InputGroupBase {
public String operator; public String operator;
public List<Integer> to_lines; public List<Integer> to_lines;
public MessagePayload notify_message; public MessagePayload notify_message;
private boolean isMeshMessage;
public String getOperator() { public String getOperator() {
return operator; return operator;
@@ -39,4 +40,12 @@ public class InputGroupBase {
public void setNotify_message(MessagePayload notify_message) { public void setNotify_message(MessagePayload notify_message) {
this.notify_message = notify_message; this.notify_message = notify_message;
} }
public boolean isMeshMessage() {
return isMeshMessage;
}
public void setMeshMessage(boolean meshMessage) {
isMeshMessage = meshMessage;
}
} }
@@ -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;
public class InputHandleFriendRequest {
private String userId;
private String friendUid;
private int status;
private boolean force;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getFriendUid() {
return friendUid;
}
public void setFriendUid(String friendUid) {
this.friendUid = friendUid;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public boolean isForce() {
return force;
}
public void setForce(boolean force) {
this.force = force;
}
}
@@ -0,0 +1,13 @@
package cn.wildfirechat.pojos;
public class InputIntValue {
public int value;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
@@ -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;
public class InputOutputDomainInfo {
public String domainId;
public String name;
public String desc;
public String email;
public String tel;
public String address;
public String extra;
public long dt;
public String getDomainId() {
return domainId;
}
public void setDomainId(String domainId) {
this.domainId = domainId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getExtra() {
return extra;
}
public void setExtra(String extra) {
this.extra = extra;
}
public long getDt() {
return dt;
}
public void setDt(long dt) {
this.dt = dt;
}
}
@@ -0,0 +1,24 @@
/*
* 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 InputOutputDomainInfoList {
public List<InputOutputDomainInfo> infos;
public List<InputOutputDomainInfo> getInfos() {
return infos;
}
public void setInfos(List<InputOutputDomainInfo> infos) {
this.infos = infos;
}
}
@@ -0,0 +1,22 @@
package cn.wildfirechat.pojos;
import java.util.List;
public class InputStringList {
private List<String> list;
public InputStringList() {
}
public InputStringList(List<String> list) {
this.list = list;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
}
@@ -0,0 +1,13 @@
package cn.wildfirechat.pojos;
public class InputStringValue {
public String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
@@ -19,18 +19,23 @@ public class OutputCheckUserOnline {
public int platform; public int platform;
public int status; //0 online, 1 have session offline public int status; //0 online, 1 have session offline
public long lastSeen; public long lastSeen;
public String packageName;
public Session(String clientId, String userId, int platform, int status, long lastSeen) { public Session() {
}
public Session(String clientId, String userId, int platform, int status, long lastSeen, String packageName) {
this.clientId = clientId; this.clientId = clientId;
this.userId = userId; this.userId = userId;
this.platform = platform; this.platform = platform;
this.status = status; this.status = status;
this.lastSeen = lastSeen; this.lastSeen = lastSeen;
this.packageName = packageName;
} }
} }
public void addSession(String userId, String clientId, int platform, int status, long lastSeen) { public void addSession(String userId, String clientId, int platform, int status, long lastSeen, String packageName) {
Session session = new Session(clientId, userId, platform, status, lastSeen); Session session = new Session(clientId, userId, platform, status, lastSeen, packageName);
sessions.add(session); sessions.add(session);
} }
@@ -0,0 +1,16 @@
/*
* 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 OutputReadData {
public String user;
public Conversation conversation;
public long readTime;
}
@@ -0,0 +1,16 @@
/*
* 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 OutputUserChatroom {
public String userId;
public String chatroomId;
public String clientId;
public int/*ProtoConstants.Platform*/ platform;
}
@@ -0,0 +1,18 @@
/*
* 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 OutputUserInfoList {
public List<InputOutputUserInfo> userInfos;
}
@@ -14,6 +14,7 @@ public class PojoGroupInfo {
String portrait; String portrait;
String owner; String owner;
int type; int type;
int member_count;
String extra; String extra;
int mute; int mute;
int join_type; int join_type;
@@ -22,6 +23,9 @@ public class PojoGroupInfo {
int max_member_count; int max_member_count;
int history_message; int history_message;
boolean super_group; boolean super_group;
boolean deleted;
long update_dt;
long member_update_dt;
public String getTarget_id() { public String getTarget_id() {
return target_id; return target_id;
@@ -126,4 +130,36 @@ public class PojoGroupInfo {
public void setSuper_group(boolean super_group) { public void setSuper_group(boolean super_group) {
this.super_group = super_group; this.super_group = super_group;
} }
public boolean isDeleted() {
return deleted;
}
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}
public long getUpdate_dt() {
return update_dt;
}
public void setUpdate_dt(long update_dt) {
this.update_dt = update_dt;
}
public int getMember_count() {
return member_count;
}
public void setMember_count(int member_count) {
this.member_count = member_count;
}
public long getMember_update_dt() {
return member_update_dt;
}
public void setMember_update_dt(long member_update_dt) {
this.member_update_dt = member_update_dt;
}
} }
@@ -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 PojoGroupInfoList {
public List<PojoGroupInfo> groupInfoList;
public List<PojoGroupInfo> getGroupInfoList() {
return groupInfoList;
}
public void setGroupInfoList(List<PojoGroupInfo> groupInfoList) {
this.groupInfoList = groupInfoList;
}
}
@@ -13,6 +13,7 @@ public class PojoGroupMember {
String alias; String alias;
int type; int type;
String extra; String extra;
long updateDt;
long createDt; long createDt;
public String getMember_id() { public String getMember_id() {
@@ -47,6 +48,14 @@ public class PojoGroupMember {
this.extra = extra; this.extra = extra;
} }
public long getUpdateDt() {
return updateDt;
}
public void setUpdateDt(long updateDt) {
this.updateDt = updateDt;
}
public long getCreateDt() { public long getCreateDt() {
return createDt; return createDt;
} }
@@ -14,6 +14,7 @@ import io.netty.util.internal.StringUtil;
public class RecallMessageData { public class RecallMessageData {
private String operator; private String operator;
private long messageUid; private long messageUid;
private boolean isUserRecall;
public String getOperator() { public String getOperator() {
return operator; return operator;
@@ -30,4 +31,12 @@ public class RecallMessageData {
public void setMessageUid(long messageUid) { public void setMessageUid(long messageUid) {
this.messageUid = messageUid; this.messageUid = messageUid;
} }
public boolean isUserRecall() {
return isUserRecall;
}
public void setUserRecall(boolean userRecall) {
isUserRecall = userRecall;
}
} }
@@ -19,6 +19,7 @@ public class SendMessageData {
private Conversation conv; private Conversation conv;
private MessagePayload payload; private MessagePayload payload;
private List<String> toUsers; private List<String> toUsers;
private boolean isMeshMessage;
public String getSender() { public String getSender() {
return sender; return sender;
@@ -52,6 +53,14 @@ public class SendMessageData {
this.toUsers = toUsers; this.toUsers = toUsers;
} }
public boolean isMeshMessage() {
return isMeshMessage;
}
public void setMeshMessage(boolean meshMessage) {
isMeshMessage = meshMessage;
}
public static boolean isValide(SendMessageData sendMessageData) { public static boolean isValide(SendMessageData sendMessageData) {
if(sendMessageData == null || if(sendMessageData == null ||
sendMessageData.getConv() == null || sendMessageData.getConv() == null ||
@@ -14,6 +14,7 @@ public class UpdateMessageContentData {
private MessagePayload payload; private MessagePayload payload;
private int distribute; private int distribute;
private int updateTimestamp; private int updateTimestamp;
private int meshLocal;
public String getOperator() { public String getOperator() {
return operator; return operator;
@@ -54,4 +55,12 @@ public class UpdateMessageContentData {
public void setUpdateTimestamp(int updateTimestamp) { public void setUpdateTimestamp(int updateTimestamp) {
this.updateTimestamp = updateTimestamp; this.updateTimestamp = updateTimestamp;
} }
public int getMeshLocal() {
return meshLocal;
}
public void setMeshLocal(int meshLocal) {
this.meshLocal = meshLocal;
}
} }
@@ -1,5 +1,7 @@
package cn.wildfirechat.pojos; package cn.wildfirechat.pojos;
import java.util.List;
public class UserOnlineStatus { public class UserOnlineStatus {
public static final int ONLINE = 0; public static final int ONLINE = 0;
public static final int OFFLINE = 1; public static final int OFFLINE = 1;
@@ -11,6 +13,9 @@ public class UserOnlineStatus {
public int status; public int status;
public long timestamp; public long timestamp;
public String packageName; public String packageName;
public int customState;
public String customText;
public List<OutputCheckUserOnline.Session> sessions;
public UserOnlineStatus() { public UserOnlineStatus() {
} }

Some files were not shown because too many files have changed in this diff Show More