Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
776c9e26c6 | ||
|
|
c7f7ce949e | ||
|
|
07b1de4ae3 | ||
|
|
7e87f9d6ab | ||
|
|
da781180a7 | ||
|
|
f1b62ad64a | ||
|
|
576fcf3e77 | ||
|
|
33f2124352 | ||
|
|
15701e9943 | ||
|
|
dc5687319a | ||
|
|
3eef24bdb9 | ||
|
|
be5a24a6fd | ||
|
|
6537b7e009 | ||
|
|
92471db413 | ||
|
|
6626237c80 | ||
|
|
c98507d9a0 | ||
|
|
d8adaf7e88 | ||
|
|
45d40e2389 | ||
|
|
33de0f3e43 | ||
|
|
a9300e8ecc | ||
|
|
368388e7bd | ||
|
|
969de83e1f | ||
|
|
8f74e54c88 | ||
|
|
efd9d5519f | ||
|
|
97b6ccb910 | ||
|
|
c51f523d6e | ||
|
|
298ce69db7 | ||
|
|
15c2d8f59e | ||
|
|
8322134e18 | ||
|
|
52b624f25e | ||
|
|
d90bab53ad | ||
|
|
4d60231c8c | ||
|
|
d08d6f0c49 | ||
|
|
effa30b546 | ||
|
|
0f688ff1df | ||
|
|
daa4767ed8 | ||
|
|
44a916892b | ||
|
|
51dd94d3a7 | ||
|
|
2609a4251c | ||
|
|
7d36775c27 | ||
|
|
6c9df5c071 | ||
|
|
2f9c4e028c | ||
|
|
a9b83a14ed | ||
|
|
919b81139d | ||
|
|
52959a5e63 | ||
|
|
31dad28fde | ||
|
|
3094089658 | ||
|
|
24d24fe1e9 | ||
|
|
47039f53b2 | ||
|
|
554243d553 | ||
|
|
b65282f8e2 | ||
|
|
a5f64df2de | ||
|
|
c7f1ea57dc | ||
|
|
c9b2de076d | ||
|
|
552fadaa87 | ||
|
|
765572db36 | ||
|
|
a5f194b385 | ||
|
|
c74cd7e290 | ||
|
|
70cf65f0c0 | ||
|
|
3bb23f92c4 | ||
|
|
804c12845e | ||
|
|
fe15a32499 | ||
|
|
06d168935d | ||
|
|
c1984d27b3 | ||
|
|
29ef46b7a0 | ||
|
|
0bdff3fd89 | ||
|
|
cd03583dab | ||
|
|
3f8fd7e5e0 | ||
|
|
fdfe71f700 | ||
|
|
35ecf7ccc6 | ||
|
|
8f798742c3 | ||
|
|
f4ea8b184c | ||
|
|
2d7f344b1a | ||
|
|
bee03cd2f8 | ||
|
|
59b1c3180f | ||
|
|
88d764fb6d | ||
|
|
08b3886238 | ||
|
|
7e73c2880b | ||
|
|
1359ce5250 | ||
|
|
56eaf938a8 | ||
|
|
6ef6ed2906 | ||
|
|
63f37e8984 | ||
|
|
337302c551 | ||
|
|
721f27a58a | ||
|
|
ced74280d8 | ||
|
|
18617c67f4 | ||
|
|
883866ce39 | ||
|
|
2e135d4794 | ||
|
|
1d6faa5796 | ||
|
|
731fa00cc9 | ||
|
|
4da9173c5f | ||
|
|
94e430cc83 | ||
|
|
7e92d1e0c5 | ||
|
|
4fa79bfeac | ||
|
|
98388a5129 | ||
|
|
1a89714df9 | ||
|
|
a855652c26 | ||
|
|
21aadd9c0b | ||
|
|
5522a8689d | ||
|
|
bf52a00304 | ||
|
|
3349e2a4e5 | ||
|
|
70f3f96f7a | ||
|
|
5e9d411f1b | ||
|
|
e74fd0c660 | ||
|
|
d1232abe39 | ||
|
|
1df192f730 | ||
|
|
f897e640fc | ||
|
|
ee6e4f96fb | ||
|
|
d14dc74566 | ||
|
|
ff75379779 |
@@ -30,27 +30,29 @@
|
||||
## 野火开源项目
|
||||
主要包括以下项目:
|
||||
|
||||
| [GitHub仓库](https://github.com/wildfirechat) | [码云仓库](https://gitee.com/wfchat) | 说明
|
||||
| ------------------------------------------------------------ | ----------------------------------------------------- | --------------------------------------------------------------------------
|
||||
| [im-server](https://github.com/wildfirechat/im-server) | [im-server](https://gitee.com/wfchat/im-server) | 野火社区版IM服务,野火IM的核心服务,处理所有IM相关业务。 |
|
||||
| [app-server](https://github.com/wildfirechat/app-server) | [app-server](https://gitee.com/wfchat/app-server) | Demo应用服务,模拟客户的应用服登陆处理逻辑及部分二次开发示例。 |
|
||||
| [robot_server](https://github.com/wildfirechat/robot_server) | [robot_server](https://gitee.com/wfchat/robot_server) | 机器人服务,演示野火机器人对接其它系统的方法。 |
|
||||
| [push_server](https://github.com/wildfirechat/push_server) | [push_server](https://gitee.com/wfchat/push_server) | 推送服务器,可以对接所有的系统厂商推送服务或者第三方推送服务。 |
|
||||
| [wf-minio](https://github.com/wildfirechat/WF-minio) | [wf-minio](https://gitee.com/wfchat/WF-minio) | 私有对象存储服务,用来支持野火IM专业版的文件存储。 |
|
||||
| [wf-janus](https://github.com/wildfirechat/wf-janus ) | [wf-janus](https://gitee.com/wfchat/wf-janus ) | 高级音视频媒体服务。 |
|
||||
| [open-platform](https://github.com/wildfirechat/open-platform) | [open-platform](https://gitee.com/wfchat/open-platform) | 野火开放平台服务。 |
|
||||
| [daily-report](https://github.com/wildfirechat/daily-report) | [daily-report](https://github.com/wildfirechat/daily-report) | 野火开放平台日报 demo服务。 |
|
||||
| [channel-platform](https://github.com/wildfirechat/channel-platform) | [channel-platform](https://gitee.com/wfchat/channel-platform) | 野火频道(公众号)平台服务。 |
|
||||
| [organization-platform](https://github.com/wildfirechat/organization-platform) | [organization-platform](https://gitee.com/wfchat/organization-platform) | 野火组织通讯录服务。 |
|
||||
| [android-chat](https://github.com/wildfirechat/android-chat) | [android-chat](https://gitee.com/wfchat/android-chat) | 野火IM Android SDK源码和App源码。 |
|
||||
| [ios-chat](https://github.com/wildfirechat/ios-chat) | [ios-chat](https://gitee.com/wfchat/ios-chat) | 野火IM iOS SDK源码和App源码。|
|
||||
| [pc-chat](https://github.com/wildfirechat/vue-pc-chat) | [pc-chat](https://gitee.com/wfchat/vue-pc-chat) | 基于[Electron](https://electronjs.org/)的PC 端,支持Windows、Mac、Linux(包括国产化linux系统和CPU)。 |
|
||||
| [web-chat](https://github.com/wildfirechat/vue-chat) | [web-chat](https://gitee.com/wfchat/vue-chat) | 野火IM Web 端, [体验地址](https://web.wildfirechat.cn)。 |
|
||||
| [wx-chat](https://github.com/wildfirechat/wx-chat) | [wx-chat](https://gitee.com/wfchat/wx-chat) | 小程序平台的Demo(支持微信、百度、阿里、字节、QQ 等小程序平台)。 |
|
||||
| [uni-chat](https://github.com/wildfirechat/uni-chat) | [uni-chat](https://gitee.com/wfchat/uni-chat) | UniApp平台移动端应用(使用原生插件)。 |
|
||||
| [uni-wfc-client](https://github.com/wildfirechat/uni-wfc-client) | [uni-wfc-client](https://gitee.com/wfchat/uni-wfc-client) | UniApp平台原生插件。已[商店](https://ext.dcloud.net.cn/plugin?id=7895)上架 |
|
||||
| [wfc_flutter_plugins](https://github.com/wildfirechat/wfc_flutter_plugins) | [flutter_imclient](https://gitee.com/wfchat/wfc_flutter_plugins) | Flutter平台原生插件,支持IM和音视频通话。 |
|
||||
| [docs](https://github.com/wildfirechat/docs) | [docs](https://gitee.com/wfchat/docs) | 野火IM相关文档,包含设计、概念、开发、使用说明,[在线查看](https://docs.wildfirechat.cn/)。 |
|
||||
| [GitHub仓库](https://github.com/wildfirechat) | [码云仓库](https://gitee.com/wfchat) | 说明
|
||||
|--------------------------------------------------------------------------------|-------------------------------------------------------------------------| --------------------------------------------------------------------------
|
||||
| [im-server](https://github.com/wildfirechat/im-server) | [im-server](https://gitee.com/wfchat/im-server) | 野火社区版IM服务,野火IM的核心服务,处理所有IM相关业务。 |
|
||||
| [app-server](https://github.com/wildfirechat/app-server) | [app-server](https://gitee.com/wfchat/app-server) | Demo应用服务,模拟客户的应用服登陆处理逻辑及部分二次开发示例。 |
|
||||
| [robot_server](https://github.com/wildfirechat/robot_server) | [robot_server](https://gitee.com/wfchat/robot_server) | 机器人服务,演示野火机器人对接其它系统的方法。 |
|
||||
| [push_server](https://github.com/wildfirechat/push_server) | [push_server](https://gitee.com/wfchat/push_server) | 推送服务器,可以对接所有的系统厂商推送服务或者第三方推送服务。 |
|
||||
| [wf-minio](https://github.com/wildfirechat/WF-minio) | [wf-minio](https://gitee.com/wfchat/WF-minio) | 私有对象存储服务,用来支持野火IM专业版的文件存储。 |
|
||||
| [wf-janus](https://github.com/wildfirechat/wf-janus ) | [wf-janus](https://gitee.com/wfchat/wf-janus ) | 高级音视频媒体服务。 |
|
||||
| [open-platform](https://github.com/wildfirechat/open-platform) | [open-platform](https://gitee.com/wfchat/open-platform) | 野火开放平台服务。 |
|
||||
| [daily-report](https://github.com/wildfirechat/daily-report) | [daily-report](https://github.com/wildfirechat/daily-report) | 野火开放平台日报 demo服务。 |
|
||||
| [channel-platform](https://github.com/wildfirechat/channel-platform) | [channel-platform](https://gitee.com/wfchat/channel-platform) | 野火频道(公众号)平台服务。 |
|
||||
| [organization-platform](https://github.com/wildfirechat/organization-platform) | [organization-platform](https://gitee.com/wfchat/organization-platform) | 野火组织通讯录服务。 |
|
||||
| [archive-server](https://github.com/wildfirechat/archive-server) | [archive-server](https://gitee.com/wfchat/archive-server) | 野火组织通讯录服务。 |
|
||||
| [android-chat](https://github.com/wildfirechat/android-chat) | [android-chat](https://gitee.com/wfchat/android-chat) | 野火IM Android SDK源码和App源码。 |
|
||||
| [ios-chat](https://github.com/wildfirechat/ios-chat) | [ios-chat](https://gitee.com/wfchat/ios-chat) | 野火IM iOS SDK源码和App源码。|
|
||||
| [pc-chat(electron)](https://github.com/wildfirechat/vue-pc-chat) | [pc-chat(electron)](https://gitee.com/wfchat/vue-pc-chat) | 基于[Electron](https://electronjs.org/)开发的PC 端 | |
|
||||
| [pc-chat(Qt)](https://github.com/wildfirechat/qt-pc-chat) | [pc-chat(Qt)](https://gitee.com/wfchat/qt-pc-chat) | 基于Qt开发的PC 端 | |
|
||||
| [web-chat](https://github.com/wildfirechat/vue-chat) | [web-chat](https://gitee.com/wfchat/vue-chat) | 野火IM Web 端, [体验地址](https://web.wildfirechat.cn)。 |
|
||||
| [wx-chat](https://github.com/wildfirechat/wx-chat) | [wx-chat](https://gitee.com/wfchat/wx-chat) | 小程序平台的Demo(支持微信、百度、阿里、字节、QQ 等小程序平台)。 |
|
||||
| [uni-chat](https://github.com/wildfirechat/uni-chat) | [uni-chat](https://gitee.com/wfchat/uni-chat) | UniApp平台移动端应用(使用原生插件)。 |
|
||||
| [uni-wfc-client](https://github.com/wildfirechat/uni-wfc-client) | [uni-wfc-client](https://gitee.com/wfchat/uni-wfc-client) | UniApp平台原生插件。已[商店](https://ext.dcloud.net.cn/plugin?id=7895)上架 |
|
||||
| [flutter-chat](https://github.com/wildfirechat/flutter-chat) | [flutter-chat](https://gitee.com/wfchat/flutter-chat) | Flutter平台原生插件,支持IM和音视频通话。 |
|
||||
| [docs](https://github.com/wildfirechat/docs) | [docs](https://gitee.com/wfchat/docs) | 野火IM相关文档,包含设计、概念、开发、使用说明,[在线查看](https://docs.wildfirechat.cn/)。 |
|
||||
|
||||
## 野火开发文档
|
||||
[在线文档](https://docs.wildfirechat.cn/)
|
||||
@@ -157,6 +159,14 @@ mvn clean package
|
||||
## 服务对象
|
||||
因为野火的使用范围比较广,难免被一些不法分子利用,国内反诈反赌力度很大,所以国内多地警方都跟我们都有过联系。***为了预防我们的产品被用于非法目的,试用及购买只能支持境内法人单位,不接受个人或者境外团体。如果我们发现产品被用于非法目的,我们会立即停止技术支持服务并且报警和配合警方调查。请用于非法目的用户绕行!***
|
||||
|
||||
## 群的性能问题
|
||||
群的大小和性能不是线性相关的,而是O(N²)的关系,这是群的特性决定的。所以社区版IM服务很难支持很大的群人数,我们建议最大群不要超过500人,像微信的群大小一样。修改方法是修改数据库中```t_settings```表中的群最大人数。
|
||||
|
||||
如果是专业版IM服务,普通群性能会有些加强,但也不会提高太多,所以我们就开发了超级群,可以支持上万群成员。关于超级群,请参考[野火超级群组](https://mp.weixin.qq.com/s/ov5ZiaEIUZuvgFBXOrcjbg)。现有客户有接近10W的群组成员能够流畅稳定地运行。
|
||||
|
||||
## 网络问题
|
||||
如果是自建机房或者私有网络,可能会有跨运营商瓶颈,详情请参考[《从野火 IM 的网络踩坑经历,聊聊跨运营商访问的那些坑》](https://mp.weixin.qq.com/s/Pa8b93oMk58fjMgwtwmePQ)。
|
||||
|
||||
## 常见问题
|
||||
请参考文档[常见问题](https://docs.wildfirechat.cn/faq/server.html)
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ message.disable_remote_search false
|
||||
##如果要避免数据库中明文存储消息内容,请打开这个开关和message.disable_remote_search开关
|
||||
message.encrypt_message_content false
|
||||
|
||||
##允许客户端撤回用户自己发送的消息时限,单位是秒。
|
||||
##允许客户端撤回用户自己发送的消息时限,单位是秒。0是不允许撤回;-1是无限制撤回。
|
||||
##Server API不受此限制,可以撤回任意时限内的消息
|
||||
##群组管理员或群主撤回群成员消息不受此限制,可以撤回任意时限内的消息。但管理员或群主撤回自己的消息还是需要准守此时间限制。
|
||||
##修改此参数需要同步修改客户端UI,客户端UI代码有判断撤回是否显示的逻辑。
|
||||
@@ -152,12 +152,43 @@ message.no_forward_admin_message false
|
||||
## 消息转发功能开启时,转发信息是否带上用户clientId和平台类型。
|
||||
message.forward_with_client_info false
|
||||
|
||||
## 消息转发功能开启时,转发信息是否带上发送者的用户信息
|
||||
message.forward_with_sender_info false
|
||||
|
||||
## 消息转发功能开启时,转发信息是否带上目标的信息,单聊时是对方用户信息,群聊时是群组信息,频道时是频道信息
|
||||
message.forward_with_target_info false
|
||||
|
||||
## 允许发送单聊消息给被封禁用户
|
||||
message.allow_send_to_forbidden_user false
|
||||
|
||||
## 机器人回调信息是否带上用户clientId和平台类型。
|
||||
robot.callback_with_client_info false
|
||||
|
||||
## 机器人回调信息是否带上发送者的用户信息
|
||||
robot.callback_with_sender_info false
|
||||
|
||||
## 机器人回调信息是否带上目标的信息,单聊时是对方用户信息,群聊时是群组信息,频道时是频道信息
|
||||
robot.callback_with_target_info false
|
||||
|
||||
## 是否允许@会话外的机器人。如果为true,单聊或者群聊时,可以@不在会话中的机器人。当机器人收到消息后,可以回复消息。
|
||||
## 如果为false,不能@不在会话中的机器人。机器人不在会话中时,也不能回复消息。
|
||||
robot.mention_external_robot true
|
||||
|
||||
## 机器人获取信息允许的字段,可以获取userId/displayName/portrait,其他需要这里配置允许。
|
||||
## 第一位(1)是name, 第二位(2)是mobile,第三(4)位是email,第四位(8)是address,第五位(16)是company,第六位(32)是extra,
|
||||
## 第七位(64)是updateDt,第八位(128)是gender,第九位(256)是social,第十位(512)是type。
|
||||
## 比如允许获取name和email就是5(1+4),允许获取name和mobile和company和type就是531(1+2+16+512),允许全部是1023(1+2+...+512)
|
||||
#robot.get_user_info_mask 1023
|
||||
|
||||
## 频道回调信息是否带上用户clientId和平台类型。
|
||||
channel.callback_with_client_info false
|
||||
|
||||
## 频道回调信息是否带上发送者的用户信息。
|
||||
channel.callback_with_sender_info false
|
||||
|
||||
## 频道回调信息是否带上频道信息
|
||||
channel.callback_with_target_info false
|
||||
|
||||
## 频道回调新方式,在新方式下,如果有callback地址就会总是回调客户端发送的消息(包括owner和订阅者)。automatic属性控制订阅者发送的消息是否发给owner, 0发,1不发。
|
||||
## 旧的方式是,automatic为0时,订阅者的消息发给owner,不转发消息到callback地址。为1时,把订阅者的消息转发给callback地址,不发给owner。
|
||||
channel.new_callback_feature true
|
||||
@@ -168,8 +199,8 @@ friend.disable_search false
|
||||
##禁止按照昵称搜索用户。
|
||||
friend.disable_nick_name_search false
|
||||
|
||||
##禁止按照用户id搜索用户,默认为true。
|
||||
friend.disable_user_id_search true
|
||||
##禁止按照用户id搜索用户,默认为false。
|
||||
friend.disable_user_id_search false
|
||||
|
||||
##禁止发送好友邀请,通过server api添加好友不受此限制(force参数需要为true)
|
||||
friend.disable_friend_request false
|
||||
@@ -186,6 +217,12 @@ friend.request_expiration_duration 604800000
|
||||
##好友请求限制频率,一个用户24小时之内允许请求好友的次数,默认不限频。
|
||||
friend.request_rate_limit 30
|
||||
|
||||
##如果搜索电话号码,24小时内搜索错误号码几次就不再允许电话号码搜素。防止有人遍历搜索电话号码
|
||||
friend.search_mobile_empty_rate_limit 5
|
||||
|
||||
##如果搜索用户,24小时内搜索次数。防止有人遍历用户名或者用户ID乱加好友。另外可以禁止ID搜索friend.disable_user_id_search
|
||||
friend.search_rate_limit 100
|
||||
|
||||
##请求添加机器人为好友时,机器人是否自动接受,默认为true
|
||||
friend.robot_auto_accept true
|
||||
|
||||
@@ -227,6 +264,10 @@ group.visible_quit_or_kickoff_notification 0
|
||||
## 是否禁止陌生人拉人入群,默认为false
|
||||
group.disable_stranger_invite false
|
||||
|
||||
## 创建群组或者加人时。可能会有成员加入失败(黑名单,或者不允许陌生人拉入群)。当出现有成员失败时,如果此开关为关,操作会失败。
|
||||
## 如果此开关打开,操作会返回成功,另外在群里发送一条通知消息 XXX 拒绝加入群组。默认为开。
|
||||
group.add_member_allow_part_success true
|
||||
|
||||
## 群组信息是否标记删除
|
||||
group.enable_mark_deletion true
|
||||
|
||||
@@ -238,6 +279,16 @@ group.enable_mark_deletion true
|
||||
## 销毁用户时,用户信息会被清空,deleted字段设置为1,这个开关控制是否保留用户昵称,默认为true。
|
||||
user.keep_display_name_when_destroy true
|
||||
|
||||
## 销毁用户时deleted字段设置为1,这个开关控制是否保留其他信息,默认是false。
|
||||
user.keep_full_info_when_destroy false
|
||||
|
||||
## 销毁用户时,如果user.keep_full_info_when_destroy为true,会保留所有信息,这个开关控制是否保留这个用户信息的电话号码,默认为false。
|
||||
## 当保留所有信息且保留电话号码时,用户如果再注册会用到原来的UID,能够看到原来用户的消息,需要考虑一下是否让已删除用户再次注册登录看到之前的消息。
|
||||
user.keep_mobile_when_destroy false
|
||||
|
||||
## 销毁用户时是否保留归属于这个用户的所有消息记录,默认为false。
|
||||
user.keep_messages_when_destroy false
|
||||
|
||||
# 好友/好友请求/用户设置 这三类数据同步的最大条目数。之前是客户第一次登录时,会把所有的对应数据一次下载到客户端,但如果有特别多的信息,会导致无法同步到客户端,
|
||||
# 因此需要分段多次同步,此开关定义了每次同步的数据的条数。此需要客户端支持,客户端SDK在2021.5.25日后支持此功能。如果确认所有客户端都在这个日志之后才可以打开此设置。
|
||||
#sync.data_part_size 1000
|
||||
@@ -289,6 +340,15 @@ qiniu.bucket_portrait_name storage
|
||||
qiniu.bucket_portrait_domain http://cdn2.wildfirechat.cn
|
||||
qiniu.bucket_favorite_name storage
|
||||
qiniu.bucket_favorite_domain http://cdn2.wildfirechat.cn
|
||||
## custom的桶是给客户预留的,客户可以上传自己的文件到这3个桶中,野火不会用到这几个桶。如果不需要,可以忽略这几个配置
|
||||
qiniu.bucket_custom1_name temp1
|
||||
qiniu.bucket_custom1_domain http://temp1.wildfirechat.cn
|
||||
qiniu.bucket_custom2_name temp2
|
||||
qiniu.bucket_custom2_domain http://temp2.wildfirechat.cn
|
||||
qiniu.bucket_custom3_name temp3
|
||||
qiniu.bucket_custom3_domain http://temp3.wildfirechat.cn
|
||||
qiniu.bucket_pan_name pan
|
||||
qiniu.bucket_pan_domain http://pan.wildfirechat.cn
|
||||
|
||||
##媒体类型分类
|
||||
#Media_Type_GENERAL = 0,
|
||||
@@ -321,6 +381,12 @@ server.multi_pc_endpoint false
|
||||
## 是否支持PAD多端登陆,当server.multi_endpoint为true时,此开关无意义,当为false时,可以单独打开PAD端多端登录。
|
||||
server.multi_pad_endpoint false
|
||||
|
||||
## 是否支持可穿戴设备多端登陆,当server.multi_endpoint为true时,此开关无意义,当为false时,可以单独打开可穿戴设备多端登录。
|
||||
server.multi_wearable_endpoint false
|
||||
|
||||
## 是否支持TV设备多端登陆,当server.multi_endpoint为true时,此开关无意义,当为false时,可以单独打开TV多端登录。
|
||||
server.multi_tv_endpoint false
|
||||
|
||||
# 多平台连接状态通知(仅当multi_endpoint为false时有效),true时移动端可以收到pc或pad或web端登录的通知。
|
||||
server.multi_platform_notification true
|
||||
|
||||
@@ -423,6 +489,10 @@ push.harmony.server.address http://localhost:8085/harmony/push
|
||||
## 如果开启 message.sensitive.forward.url 配置,命中敏感词的消息还会被回调到这个地址
|
||||
sensitive.filter.type 2
|
||||
|
||||
## 敏感词是否只处理消息。如果为true,只过滤消息;如果为false,会同时过滤用户昵称、群组名和群昵称。
|
||||
## 除了消息之外的信息只支持内部敏感词处理,不支持外置审核。
|
||||
sensitive.only_message false
|
||||
|
||||
## 敏感词添加或者删除有2种方式,一种是通过Server API进行,这种方式会立即生效。另外一种方法是修改数据库,直接中数据库的t_sensitive_word表中处理
|
||||
## 修改数据库的方法不会立即生效,IM服务会2个小时重新加载一次敏感词。所以如果直接修改敏感词表,需要等2个小时,或者重启才能生效。
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
CREATE INDEX `user_gid_dt_index` ON `t_group_member` (`_gid`, `_dt`);
|
||||
@@ -0,0 +1 @@
|
||||
insert into t_settings(`id`, `_value`,`_desc`) values (2, '文件传输助手,客服,官方', '禁止使用名称,如果有多个,以英文逗号隔开。直接修改数据库,不用重启IM服务');
|
||||
+1
@@ -0,0 +1 @@
|
||||
alter table `t_messages` modify column `_target` varchar(129) NOT NULL;
|
||||
+1
@@ -0,0 +1 @@
|
||||
ALTER TABLE `t_user_session` ADD COLUMN `_ip` varchar(40) DEFAULT '';
|
||||
+1
@@ -0,0 +1 @@
|
||||
CREATE INDEX `user_gid_type_index` ON `t_group_member` (`_gid`, `_type`);
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
|
||||
DROP TABLE IF EXISTS `t_conference`;
|
||||
CREATE TABLE `t_conference` (
|
||||
`_id` varchar(64) NOT NULL PRIMARY KEY,
|
||||
`_des` varchar(64) NOT NULL,
|
||||
`_pin` varchar(16) NOT NULL,
|
||||
`_max_publishers` int(11) NOT NULL DEFAULT 0,
|
||||
`_bitrate` int(11) NOT NULL DEFAULT 0,
|
||||
`_advance` tinyint NOT NULL DEFAULT 0,
|
||||
`_recording` tinyint NOT NULL DEFAULT 0,
|
||||
`_create_dt` bigint(20) NOT NULL
|
||||
);
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
DROP TABLE IF EXISTS `t_join_group_request`;
|
||||
CREATE TABLE `t_join_group_request` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_gid` varchar(64) NOT NULL,
|
||||
`_mid` varchar(64) NOT NULL,
|
||||
`_request_uid` varchar(64) NOT NULL,
|
||||
`_accept_uid` varchar(64) DEFAULT NULL,
|
||||
`_reason` TEXT DEFAULT NULL,
|
||||
`_extra` TEXT DEFAULT NULL,
|
||||
`_status` tinyint NOT NULL DEFAULT 0,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
`_read_status` tinyint DEFAULT 0,
|
||||
UNIQUE INDEX `join_group_request_key_index` (`_uid` DESC, `_gid` DESC, `_mid` DESC, `_request_uid` DESC),
|
||||
INDEX `join_group_request_gm_index` (`_gid` DESC, `_mid` DESC),
|
||||
INDEX `join_group_request_sync_index` (`_uid` DESC, `_dt` DESC)
|
||||
);
|
||||
+1
@@ -0,0 +1 @@
|
||||
alter table t_friend add index `friend_uid_index` (`_friend_uid`);
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE `t_conference` ADD COLUMN `_delete_by` varchar(64) DEFAULT '';
|
||||
ALTER TABLE `t_conference` ADD COLUMN `_deleted` tinyint DEFAULT 0;
|
||||
ALTER TABLE `t_conference` ADD COLUMN `_delete_dt` bigint(20) DEFAULT 0;
|
||||
@@ -0,0 +1 @@
|
||||
CREATE INDEX `user_gid_mid_dt_index` ON `t_group_member` (`_gid`, `_mid`, `_dt`);
|
||||
@@ -0,0 +1,2 @@
|
||||
DROP INDEX `user_gid_mid_dt_index` ON `t_group_member`;
|
||||
CREATE INDEX `user_gid_dt_index` ON `t_group_member` (`_gid`, `_dt`);
|
||||
@@ -0,0 +1 @@
|
||||
insert into t_settings(`id`, `_value`,`_desc`) values (2, '文件传输助手,客服,官方', '禁止使用名称,如果有多个,以英文逗号隔开。直接修改数据库,不用重启IM服务');
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
alter table `t_messages` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_0` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_1` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_2` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_3` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_4` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_5` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_6` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_7` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_8` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_9` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_10` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_11` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_12` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_13` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_14` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_15` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_16` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_17` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_18` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_19` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_20` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_21` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_22` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_23` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_24` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_25` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_26` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_27` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_28` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_29` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_30` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_31` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_32` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_33` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_34` modify column `_target` varchar(129) NOT NULL;
|
||||
alter table `t_messages_35` modify column `_target` varchar(129) NOT NULL;
|
||||
+1
@@ -0,0 +1 @@
|
||||
ALTER TABLE `t_user_session` ADD COLUMN `_ip` varchar(40) DEFAULT '';
|
||||
@@ -0,0 +1 @@
|
||||
CREATE INDEX `user_gid_type_index` ON `t_group_member` (`_gid`, `_type`);
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
|
||||
DROP TABLE IF EXISTS `t_conference`;
|
||||
CREATE TABLE `t_conference` (
|
||||
`_id` varchar(64) NOT NULL PRIMARY KEY,
|
||||
`_des` varchar(64) NOT NULL,
|
||||
`_pin` varchar(16) NOT NULL,
|
||||
`_max_publishers` int(11) NOT NULL DEFAULT 0,
|
||||
`_bitrate` int(11) NOT NULL DEFAULT 0,
|
||||
`_advance` tinyint NOT NULL DEFAULT 0,
|
||||
`_recording` tinyint NOT NULL DEFAULT 0,
|
||||
`_create_dt` bigint(20) NOT NULL
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
DROP TABLE IF EXISTS `t_join_group_request`;
|
||||
CREATE TABLE `t_join_group_request` (
|
||||
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
`_uid` varchar(64) NOT NULL,
|
||||
`_gid` varchar(64) NOT NULL,
|
||||
`_mid` varchar(64) NOT NULL,
|
||||
`_request_uid` varchar(64) NOT NULL,
|
||||
`_accept_uid` varchar(64) DEFAULT NULL,
|
||||
`_reason` TEXT DEFAULT NULL,
|
||||
`_extra` TEXT DEFAULT NULL,
|
||||
`_status` tinyint NOT NULL DEFAULT 0,
|
||||
`_dt` bigint(20) NOT NULL,
|
||||
`_read_status` tinyint DEFAULT 0,
|
||||
UNIQUE INDEX `join_group_request_key_index` (`_uid` DESC, `_gid` DESC, `_mid` DESC, `_request_uid` DESC),
|
||||
INDEX `join_group_request_gm_index` (`_gid` DESC, `_mid` DESC),
|
||||
INDEX `join_group_request_sync_index` (`_uid` DESC, `_dt` DESC)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_unicode_ci;
|
||||
+1
@@ -0,0 +1 @@
|
||||
alter table t_friend add index `friend_uid_index` (`_friend_uid`);
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE `t_conference` ADD COLUMN `_delete_by` varchar(64) DEFAULT '';
|
||||
ALTER TABLE `t_conference` ADD COLUMN `_deleted` tinyint DEFAULT 0;
|
||||
ALTER TABLE `t_conference` ADD COLUMN `_delete_dt` bigint(20) DEFAULT 0;
|
||||
+1
-55
@@ -5,7 +5,7 @@
|
||||
<relativePath>../</relativePath>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.3.3</version>
|
||||
<version>1.4.6</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>moquette-broker</artifactId>
|
||||
@@ -211,60 +211,6 @@
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Generate the test-jar -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- Includes to generate OSGi headers -->
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
||||
</archive>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>bundle-manifest</id>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>manifest</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>pl.project13.maven</groupId>
|
||||
<artifactId>git-commit-id-plugin</artifactId>
|
||||
|
||||
@@ -36,6 +36,8 @@ public class PushMessage {
|
||||
public String language;
|
||||
public boolean republish;
|
||||
public long messageId;
|
||||
public long callStartUid;
|
||||
public int existBadgeNumber;
|
||||
|
||||
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) {
|
||||
this.sender = sender;
|
||||
|
||||
@@ -81,10 +81,6 @@ public class PushServer {
|
||||
}
|
||||
|
||||
MemorySessionStore.Session session = sessionsStore.getSession(deviceId);
|
||||
int badge = session.getUnReceivedMsgs();
|
||||
if (badge <= 0) {
|
||||
badge = 1;
|
||||
}
|
||||
if (StringUtil.isNullOrEmpty(session.getDeviceToken())) {
|
||||
LOG.warn("Device token is empty for device {}", deviceId);
|
||||
return;
|
||||
@@ -94,20 +90,24 @@ public class PushServer {
|
||||
pushMessage.pushType = session.getPushType();
|
||||
pushMessage.pushContent = pushContent;
|
||||
pushMessage.deviceToken = session.getDeviceToken();
|
||||
pushMessage.unReceivedMsg = badge;
|
||||
pushMessage.userId = session.getUsername();
|
||||
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
|
||||
session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyPad ||
|
||||
session.getPlatform() == ProtoConstants.Platform.Platform_AppleTV ||
|
||||
session.getPlatform() == ProtoConstants.Platform.Platform_AndroidTV ||
|
||||
session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyTV ||
|
||||
session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyWearable ||
|
||||
session.getPlatform() == ProtoConstants.Platform.Platform_AndroidWearable
|
||||
) {
|
||||
String url = androidPushServerUrl;
|
||||
if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS || session.getPlatform() == ProtoConstants.Platform.Platform_iPad) {
|
||||
if (session.getPlatform() == ProtoConstants.Platform.Platform_iOS || session.getPlatform() == ProtoConstants.Platform.Platform_iPad || session.getPlatform() == ProtoConstants.Platform.Platform_AppleTV) {
|
||||
url = iOSPushServerUrl;
|
||||
pushMessage.voipDeviceToken = session.getVoipDeviceToken();
|
||||
} else if (session.getPlatform() == ProtoConstants.Platform.Platform_Harmony || session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyPad) {
|
||||
} else if (session.getPlatform() == ProtoConstants.Platform.Platform_Harmony || session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyPad || session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyWearable || session.getPlatform() == ProtoConstants.Platform.Platform_HarmonyTV) {
|
||||
url = harmonyPushServerUrl;
|
||||
}
|
||||
HttpUtils.httpJsonPost(url, gson.toJson(pushMessage, pushMessage.getClass()), POST_TYPE_Push);
|
||||
|
||||
@@ -35,6 +35,9 @@ public class ThreadPoolExecutorWrapper {
|
||||
executor.execute(() -> {
|
||||
try {
|
||||
task.run();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
LOG.info("execute error = {}", e.toString());
|
||||
} finally {
|
||||
int endCount = runCounter.decrementAndGet();
|
||||
LOG.debug("Finish task and current task count {} use time {}", endCount, System.currentTimeMillis()-startTime);
|
||||
|
||||
@@ -8,9 +8,13 @@
|
||||
|
||||
package com.xiaoleilu.loServer.action;
|
||||
|
||||
import cn.wildfirechat.common.IMExceptionEvent;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.action.channel.ChannelAction;
|
||||
import com.xiaoleilu.loServer.action.robot.RobotAction;
|
||||
import com.xiaoleilu.loServer.annotation.RequireAuthentication;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
@@ -23,7 +27,10 @@ import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import win.liyufan.im.RateLimiter;
|
||||
import win.liyufan.im.Utility;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@@ -38,6 +45,7 @@ import static io.moquette.BrokerConstants.*;
|
||||
*/
|
||||
|
||||
abstract public class Action {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Action.class);
|
||||
public static IMessagesStore messagesStore = null;
|
||||
public static ISessionsStore sessionsStore = null;
|
||||
protected static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();
|
||||
@@ -136,7 +144,7 @@ abstract public class Action {
|
||||
errorCode = ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
RestResult result = RestResult.resultOf(errorCode, errorCode.getMsg(), RestResult.resultOf(errorCode));
|
||||
RestResult result = RestResult.resultOf(errorCode, errorCode.getMsg(), null);
|
||||
response.setContent(gson.toJson(result));
|
||||
response.send();
|
||||
}
|
||||
@@ -153,9 +161,22 @@ abstract public class Action {
|
||||
FullHttpRequest fullHttpRequest = (FullHttpRequest) request;
|
||||
byte[] bytes = Utils.readBytesAndRewind(fullHttpRequest.content());
|
||||
String content = new String(bytes, StandardCharsets.UTF_8);//contribute by JiaRG from github
|
||||
|
||||
T t = gson.fromJson(content, cls);
|
||||
return t;
|
||||
|
||||
try {
|
||||
T t = gson.fromJson(content, cls);
|
||||
return t;
|
||||
} catch (JsonSyntaxException e) {
|
||||
e.printStackTrace();
|
||||
LOG.error("Object {} from json {} failure", cls.getName(), content);
|
||||
int exception = IMExceptionEvent.EventType.ADMIN_API_Exception;
|
||||
if (this instanceof RobotAction) {
|
||||
exception = IMExceptionEvent.EventType.ROBOT_API_Exception;
|
||||
} else if (this instanceof ChannelAction) {
|
||||
exception = IMExceptionEvent.EventType.CHANNEL_API_Exception;
|
||||
}
|
||||
Utility.printExecption(LOG, e, exception);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package com.xiaoleilu.loServer.action;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.file.Files;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
@@ -13,6 +16,7 @@ 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.util.StringUtil;
|
||||
import com.xiaoleilu.loServer.ServerSetting;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
import com.xiaoleilu.loServer.handler.Response;
|
||||
@@ -90,11 +94,26 @@ public class FileAction extends Action {
|
||||
}
|
||||
|
||||
response.setContent(file);
|
||||
response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
|
||||
if (isAudioOrVideoFile(file.getName())) {
|
||||
response.setHeader("Accept-Ranges", "bytes");
|
||||
} else {
|
||||
response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isAudioOrVideoFile(String name) {
|
||||
try {
|
||||
if (StringUtil.isNullOrEmpty(name)) return false;
|
||||
|
||||
String mimeType = Files.probeContentType(new File(name).toPath());
|
||||
return mimeType != null && (mimeType.startsWith("audio/") || mimeType.startsWith("video/"));
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Pattern INSECURE_URI = Pattern.compile(".*[<>&\"].*");
|
||||
private static final SimpleDateFormat HTTP_DATE_FORMATER = new SimpleDateFormat(HTTP_DATETIME_PATTERN, Locale.US);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ package com.xiaoleilu.loServer.action;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import com.xiaoleilu.loServer.annotation.HttpMethod;
|
||||
import com.xiaoleilu.loServer.annotation.Route;
|
||||
import com.xiaoleilu.loServer.handler.Request;
|
||||
@@ -28,7 +29,9 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Base64;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Route("/route")
|
||||
@@ -111,6 +114,12 @@ public class RouteAction extends Action {
|
||||
WFCMessage.IMHttpWrapper wrapper = WFCMessage.IMHttpWrapper.parseFrom(bytes);
|
||||
String token = wrapper.getToken();
|
||||
String userId = Tokenor.getUserId(token.getBytes());
|
||||
|
||||
String remote = ((InetSocketAddress) ctx.channel().remoteAddress())
|
||||
.getAddress().getHostAddress();
|
||||
String ip = computeRealIp(request.getHeaders(), remote);
|
||||
|
||||
|
||||
LOG.info("RouteAction token={}, userId={}", token, userId);
|
||||
if (userId == null) {
|
||||
sendResponse(response, ErrorCode.ERROR_CODE_TOKEN_ERROR, null);
|
||||
@@ -119,6 +128,8 @@ public class RouteAction extends Action {
|
||||
@Override
|
||||
public void onSuccess(byte[] result) {
|
||||
sendResponse(response, null, result);
|
||||
//save ip after success response.
|
||||
sessionsStore.updateSessionIp(userId, wrapper.getClientId(), ip);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -147,6 +158,20 @@ public class RouteAction extends Action {
|
||||
return true;
|
||||
}
|
||||
|
||||
private String computeRealIp(Map<String, String> h, String remote) {
|
||||
String xff = h.get("X-Forwarded-For");
|
||||
if (xff != null && !xff.isEmpty() && !"unknown".equalsIgnoreCase(xff)) {
|
||||
int idx = xff.indexOf(',');
|
||||
String first = (idx > 0 ? xff.substring(0, idx) : xff).trim();
|
||||
return first;
|
||||
}
|
||||
String xri = h.get("X-Real-IP");
|
||||
if (xri != null && !xri.isEmpty() && !"unknown".equalsIgnoreCase(xri)) {
|
||||
return xri;
|
||||
}
|
||||
return remote;
|
||||
}
|
||||
|
||||
private void sendResponse(Response response, ErrorCode errorCode, byte[] contents) {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
if (contents == null) {
|
||||
|
||||
@@ -24,6 +24,8 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
@@ -213,7 +215,7 @@ public class UploadFileAction extends Action {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
remoteFileName = getSafeFileName(remoteFileName);
|
||||
|
||||
String remoteFileExt = "";
|
||||
if (remoteFileName.lastIndexOf(".") == -1) {
|
||||
@@ -284,9 +286,10 @@ public class UploadFileAction extends Action {
|
||||
|
||||
savedThunkSize += readableBytesSize;
|
||||
offset += readableBytesSize;
|
||||
byteBuf.release();
|
||||
byteBuf = null;
|
||||
|
||||
if (savedThunkSize >= remoteFileSize) {
|
||||
byteBuf.release();
|
||||
fileUpload.release();
|
||||
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
@@ -338,6 +341,15 @@ public class UploadFileAction extends Action {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static String getSafeFileName(String originalFilename) {
|
||||
// Paths.get() 会解析路径,getFileName() 只取最后一部分(纯文件名)
|
||||
Path filenamePath = Paths.get(originalFilename.trim());
|
||||
String safeFilename = filenamePath.getFileName().toString();
|
||||
// 额外过滤特殊字符(可选,根据业务需要)
|
||||
safeFilename = safeFilename.replaceAll("[\\\\/:*?\"<>|]", "_");
|
||||
return safeFilename.isEmpty() ? "default_file_" + System.currentTimeMillis() : safeFilename;
|
||||
}
|
||||
|
||||
public static void put(File file, long pos, byte[] data) throws Exception {
|
||||
RandomAccessFile raf = null;
|
||||
try {
|
||||
|
||||
@@ -51,14 +51,7 @@ public class AliasPutAction extends AdminAction {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeBytes(result);
|
||||
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
byte[] data = new byte[byteBuf.readableBytes()];
|
||||
byteBuf.readBytes(data);
|
||||
String channelId = new String(data);
|
||||
return new Result(ErrorCode.ERROR_CODE_SUCCESS, new OutputCreateChannel(channelId));
|
||||
} else {
|
||||
return new Result(errorCode);
|
||||
}
|
||||
return new Result(errorCode);
|
||||
});
|
||||
return false;
|
||||
} else {
|
||||
|
||||
@@ -53,8 +53,11 @@ public class CreateChannelAction extends AdminAction {
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
byte[] data = new byte[byteBuf.readableBytes()];
|
||||
byteBuf.readBytes(data);
|
||||
String channelId = new String(data);
|
||||
return new Result(ErrorCode.ERROR_CODE_SUCCESS, new OutputCreateChannel(channelId));
|
||||
String str = new String(data);
|
||||
String[] ss = str.split("\\|");
|
||||
String channelId = ss[0];
|
||||
String secret = ss[1];
|
||||
return new Result(ErrorCode.ERROR_CODE_SUCCESS, new OutputCreateChannel(channelId, secret));
|
||||
} else {
|
||||
return new Result(errorCode);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class CreateUserAction extends AdminAction {
|
||||
if (inputCreateUser.getName() != null)
|
||||
newUserBuilder.setName(inputCreateUser.getName());
|
||||
if (inputCreateUser.getDisplayName() != null)
|
||||
newUserBuilder.setDisplayName(StringUtil.isNullOrEmpty(inputCreateUser.getDisplayName()) ? inputCreateUser.getName() : inputCreateUser.getDisplayName());
|
||||
newUserBuilder.setDisplayName(inputCreateUser.getDisplayName());
|
||||
if (inputCreateUser.getPortrait() != null)
|
||||
newUserBuilder.setPortrait(inputCreateUser.getPortrait());
|
||||
if (inputCreateUser.getEmail() != null)
|
||||
@@ -65,11 +65,8 @@ public class CreateUserAction extends AdminAction {
|
||||
newUserBuilder.setAddress(inputCreateUser.getAddress());
|
||||
if (inputCreateUser.getCompany() != null)
|
||||
newUserBuilder.setCompany(inputCreateUser.getCompany());
|
||||
|
||||
if (inputCreateUser.getSocial() != null)
|
||||
newUserBuilder.setSocial(inputCreateUser.getSocial());
|
||||
|
||||
|
||||
if (inputCreateUser.getMobile() != null)
|
||||
newUserBuilder.setMobile(inputCreateUser.getMobile());
|
||||
newUserBuilder.setGender(inputCreateUser.getGender());
|
||||
|
||||
@@ -11,12 +11,17 @@ package com.xiaoleilu.loServer.action.admin;
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputUpdateFriendExtra;
|
||||
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.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
@Route(APIPath.Friend_Set_Extra)
|
||||
@HttpMethod("POST")
|
||||
@@ -31,8 +36,17 @@ public class FriendExtraPutAction extends AdminAction {
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputUpdateFriendExtra input = getRequestBody(request.getNettyRequest(), InputUpdateFriendExtra.class);
|
||||
ErrorCode errorCode = messagesStore.setFriendExtraRequest(input.getOperator(), input.getTargetId(), input.getExtra(), new long[1]);
|
||||
setResponseContent(RestResult.resultOf(errorCode), response);
|
||||
if (input != null && !StringUtil.isNullOrEmpty(input.getOperator()) && !StringUtil.isNullOrEmpty(input.getTargetId())) {
|
||||
sendApiMessage(response, input.getOperator(), IMTopic.SetFriendExtraTopic, WFCMessage.StringPair.newBuilder().setKey(input.getTargetId()).setValue(input.getExtra()==null?"":input.getExtra()).build().toByteArray(), result -> {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeBytes(result);
|
||||
ErrorCode errorCode = ErrorCode.fromCode(byteBuf.readByte());
|
||||
return new Result(errorCode);
|
||||
});
|
||||
return false;
|
||||
} else {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package 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.util.internal.StringUtil;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Route(APIPath.User_Get_All_Robots)
|
||||
@HttpMethod("POST")
|
||||
public class GetAllRobotAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputGetUserList input = getRequestBody(request.getNettyRequest(), InputGetUserList.class);
|
||||
if (input != null && input.count > 0 && input.offset >= 0) {
|
||||
List<WFCMessage.Robot> robots = messagesStore.getRobotInfoList(input.count, input.offset);
|
||||
|
||||
OutputGetRobotList outputGetUserList = new OutputGetRobotList();
|
||||
outputGetUserList.robotInfoList = new ArrayList<>();
|
||||
robots.forEach(robotData -> {
|
||||
WFCMessage.User userInfoData = messagesStore.getUserInfo(robotData.getUid());
|
||||
if (userInfoData != null && !StringUtil.isNullOrEmpty(userInfoData.getName()) && userInfoData.getDeleted() ==0) {
|
||||
OutputRobot outputRobot = new OutputRobot();
|
||||
outputRobot.fromUser(userInfoData);
|
||||
outputRobot.fromRobot(robotData, true);
|
||||
outputGetUserList.robotInfoList.add(outputRobot);
|
||||
}
|
||||
});
|
||||
|
||||
RestResult result = RestResult.ok(outputGetUserList);
|
||||
setResponseContent(result, response);
|
||||
} else {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import win.liyufan.im.GitRepositoryState;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.Base64;
|
||||
@@ -53,7 +54,7 @@ public class GetIMTokenAction extends AdminAction {
|
||||
|
||||
LOG.info("get im token success {},{},{}", userId, input.getClientId(), token.substring(0, Math.min(10, token.length())));
|
||||
|
||||
return new Result(errorCode1, new OutputGetIMTokenData(userId, token));
|
||||
return new Result(errorCode1, new OutputGetIMTokenData(userId, token, GitRepositoryState.globalLabel));
|
||||
} else {
|
||||
return new Result(errorCode1);
|
||||
}
|
||||
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputGetPresignedUploadUrl;
|
||||
import cn.wildfirechat.pojos.OutputPresignedUploadUrl;
|
||||
import com.qiniu.util.Auth;
|
||||
import com.xiaoleilu.loServer.RestResult;
|
||||
import com.xiaoleilu.loServer.action.robot.RobotAction;
|
||||
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.server.config.MediaServerConfig;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Route(APIPath.Get_Presigned_Upload_Url)
|
||||
@HttpMethod("POST")
|
||||
public class GetUploadUrlAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
if(!MediaServerConfig.USER_QINIU) {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
return true;
|
||||
}
|
||||
|
||||
InputGetPresignedUploadUrl inputUserId = getRequestBody(request.getNettyRequest(), InputGetPresignedUploadUrl.class);
|
||||
|
||||
if (StringUtil.isNullOrEmpty(inputUserId.contentType)) {
|
||||
inputUserId.contentType = "application/octet-stream";
|
||||
}
|
||||
String uuid = UUID.randomUUID().toString().replace("-", "");
|
||||
inputUserId.fileName = uuid + inputUserId.fileName;
|
||||
|
||||
int type = inputUserId.mediaType;
|
||||
String bucketName;
|
||||
String bucketDomain;
|
||||
switch (type) {
|
||||
case 0:
|
||||
default:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_GENERAL_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_GENERAL_DOMAIN;
|
||||
break;
|
||||
case 1:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_IMAGE_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_IMAGE_DOMAIN;
|
||||
break;
|
||||
case 2:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_VOICE_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_VOICE_DOMAIN;
|
||||
break;
|
||||
case 3:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_VIDEO_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_VIDEO_DOMAIN;
|
||||
break;
|
||||
case 4:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_FILE_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_FILE_DOMAIN;
|
||||
break;
|
||||
case 5:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_PORTRAIT_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_PORTRAIT_DOMAIN;
|
||||
break;
|
||||
case 6:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_FAVORITE_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_FAVORITE_DOMAIN;
|
||||
break;
|
||||
case 7:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_STICKER_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_STICKER_DOMAIN;
|
||||
break;
|
||||
case 8:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_MOMENTS_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_MOMENTS_DOMAIN;
|
||||
break;
|
||||
case 9:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM1_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM1_DOMAIN;
|
||||
break;
|
||||
case 10:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM2_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM2_DOMAIN;
|
||||
break;
|
||||
case 11:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM3_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM3_DOMAIN;
|
||||
break;
|
||||
case 12:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_PAN_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_PAN_DOMAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
if(StringUtil.isNullOrEmpty(bucketName)) {
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_GENERAL_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_GENERAL_DOMAIN;
|
||||
}
|
||||
|
||||
String key = inputUserId.fileName;
|
||||
Auth auth = Auth.create(MediaServerConfig.QINIU_ACCESS_KEY, MediaServerConfig.QINIU_SECRET_KEY);
|
||||
String token = auth.uploadToken(bucketName, key);
|
||||
String downloadUrl = bucketDomain + "/" + key;
|
||||
String uploadUrl = "https://" + MediaServerConfig.QINIU_SERVER_URL + "?" + token + "?" + key;
|
||||
|
||||
OutputPresignedUploadUrl outputPresignedUploadUrl = new OutputPresignedUploadUrl();
|
||||
outputPresignedUploadUrl.uploadUrl = uploadUrl;
|
||||
outputPresignedUploadUrl.downloadUrl = downloadUrl;
|
||||
outputPresignedUploadUrl.type = 1;
|
||||
setResponseContent(RestResult.ok(outputPresignedUploadUrl), response);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,7 @@ public class GetUserAction extends AdminAction {
|
||||
}
|
||||
|
||||
RestResult result;
|
||||
if (user == null || user.getDeleted() > 0) {
|
||||
if (user == null || (user.getDeleted() > 0 && !inputUserId.isIncludeDeleted())) {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
|
||||
} else {
|
||||
result = RestResult.ok(InputOutputUserInfo.fromPbUser(user));
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.admin;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputRobotId;
|
||||
import cn.wildfirechat.pojos.InputUserId;
|
||||
import cn.wildfirechat.pojos.OutputRobot;
|
||||
import cn.wildfirechat.pojos.OutputStringList;
|
||||
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;
|
||||
|
||||
@Route(APIPath.User_Get_User_Robots)
|
||||
@HttpMethod("POST")
|
||||
public class GetUserRobotsAction 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);
|
||||
if (inputUserId != null
|
||||
&& (!StringUtil.isNullOrEmpty(inputUserId.getUserId()))) {
|
||||
RestResult result = RestResult.ok(new OutputStringList(messagesStore.getUserRobotIds(inputUserId.getUserId())));
|
||||
setResponseContent(result, response);
|
||||
} else {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package 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_By_Mobile)
|
||||
@HttpMethod("POST")
|
||||
public class GetUsersByMobileAction extends AdminAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
InputGetUserInfo email = getRequestBody(request.getNettyRequest(), InputGetUserInfo.class);
|
||||
if (!StringUtil.isNullOrEmpty(email.getMobile())) {
|
||||
List<WFCMessage.User> users = messagesStore.getUserInfosByMobile(email.getMobile(), email.isIncludeDeleted());
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ public class SendMessageAction extends AdminAction {
|
||||
} else {
|
||||
return new Result(errorCode);
|
||||
}
|
||||
});
|
||||
}, sendMessageData.isUserMessage());
|
||||
return false;
|
||||
} else {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
|
||||
@@ -105,18 +105,6 @@ abstract public class ChannelAction extends Action {
|
||||
response.send();
|
||||
}
|
||||
|
||||
protected <T> T getRequestBody(HttpRequest request, Class<T> cls) {
|
||||
if (request instanceof FullHttpRequest) {
|
||||
FullHttpRequest fullHttpRequest = (FullHttpRequest) request;
|
||||
byte[] bytes = Utils.readBytesAndRewind(fullHttpRequest.content());
|
||||
String content = new String(bytes, StandardCharsets.UTF_8);
|
||||
|
||||
T t = gson.fromJson(content, cls);
|
||||
return t;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void sendApiMessage(Response response, String topic, byte[] message, Callback callback) {
|
||||
sendApiMessage(response, channelInfo.getOwner(), topic, message, callback);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.robot;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputOutputUserInfo;
|
||||
import cn.wildfirechat.pojos.InputStringList;
|
||||
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.Robot_User_Batch_Get_Infos)
|
||||
@HttpMethod("POST")
|
||||
public class GetBatchUserAction extends RobotAction {
|
||||
|
||||
@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<>();
|
||||
int mask = messagesStore.getRobotGetUserInfoMask();
|
||||
for (String userId : inputUserId.getList()) {
|
||||
WFCMessage.User user = messagesStore.getUserInfo(userId);
|
||||
if(user == null || StringUtil.isNullOrEmpty(user.getName())) {
|
||||
continue;
|
||||
}
|
||||
InputOutputUserInfo inputOutputUserInfo = InputOutputUserInfo.fromPbUser(user);
|
||||
if((mask & 1) == 0) {
|
||||
inputOutputUserInfo.setName(null);
|
||||
}
|
||||
if((mask & 2) == 0) {
|
||||
inputOutputUserInfo.setMobile(null);
|
||||
}
|
||||
if((mask & 4) == 0) {
|
||||
inputOutputUserInfo.setEmail(null);
|
||||
}
|
||||
if((mask & 8) == 0) {
|
||||
inputOutputUserInfo.setAddress(null);
|
||||
}
|
||||
if((mask & 16) == 0) {
|
||||
inputOutputUserInfo.setCompany(null);
|
||||
}
|
||||
if((mask & 32) == 0) {
|
||||
inputOutputUserInfo.setExtra(null);
|
||||
}
|
||||
if((mask & 64) == 0) {
|
||||
inputOutputUserInfo.setUpdateDt(0);
|
||||
}
|
||||
if((mask & 128) == 0) {
|
||||
inputOutputUserInfo.setGender(0);
|
||||
}
|
||||
if((mask & 256) == 0) {
|
||||
inputOutputUserInfo.setSocial(null);
|
||||
}
|
||||
if((mask & 512) == 0) {
|
||||
inputOutputUserInfo.setType(0);
|
||||
}
|
||||
res.userInfos.add(inputOutputUserInfo);
|
||||
}
|
||||
RestResult result = RestResult.ok(res);
|
||||
setResponseContent(result, response);
|
||||
} else {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.robot;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.InputGetPresignedUploadUrl;
|
||||
import cn.wildfirechat.pojos.InputGetUserInfo;
|
||||
import cn.wildfirechat.pojos.InputOutputUserInfo;
|
||||
import cn.wildfirechat.pojos.OutputPresignedUploadUrl;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.qiniu.util.Auth;
|
||||
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.moquette.server.config.MediaServerConfig;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.*;
|
||||
|
||||
@Route(APIPath.Robot_Get_Presigned_Upload_Url)
|
||||
@HttpMethod("POST")
|
||||
public class GetUploadUrlAction extends RobotAction {
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
if(!MediaServerConfig.USER_QINIU) {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
return true;
|
||||
}
|
||||
|
||||
InputGetPresignedUploadUrl inputUserId = getRequestBody(request.getNettyRequest(), InputGetPresignedUploadUrl.class);
|
||||
|
||||
if (StringUtil.isNullOrEmpty(inputUserId.contentType)) {
|
||||
inputUserId.contentType = "application/octet-stream";
|
||||
}
|
||||
String uuid = UUID.randomUUID().toString().replace("-", "");
|
||||
inputUserId.fileName = uuid + inputUserId.fileName;
|
||||
|
||||
int type = inputUserId.mediaType;
|
||||
String bucketName;
|
||||
String bucketDomain;
|
||||
switch (type) {
|
||||
case 0:
|
||||
default:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_GENERAL_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_GENERAL_DOMAIN;
|
||||
break;
|
||||
case 1:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_IMAGE_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_IMAGE_DOMAIN;
|
||||
break;
|
||||
case 2:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_VOICE_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_VOICE_DOMAIN;
|
||||
break;
|
||||
case 3:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_VIDEO_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_VIDEO_DOMAIN;
|
||||
break;
|
||||
case 4:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_FILE_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_FILE_DOMAIN;
|
||||
break;
|
||||
case 5:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_PORTRAIT_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_PORTRAIT_DOMAIN;
|
||||
break;
|
||||
case 6:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_FAVORITE_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_FAVORITE_DOMAIN;
|
||||
break;
|
||||
case 7:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_STICKER_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_STICKER_DOMAIN;
|
||||
break;
|
||||
case 8:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_MOMENTS_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_MOMENTS_DOMAIN;
|
||||
break;
|
||||
case 9:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM1_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM1_DOMAIN;
|
||||
break;
|
||||
case 10:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM2_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM2_DOMAIN;
|
||||
break;
|
||||
case 11:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM3_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM3_DOMAIN;
|
||||
break;
|
||||
case 12:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_PAN_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_PAN_DOMAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
if(StringUtil.isNullOrEmpty(bucketName)) {
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_GENERAL_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_GENERAL_DOMAIN;
|
||||
}
|
||||
|
||||
String key = inputUserId.fileName;
|
||||
Auth auth = Auth.create(MediaServerConfig.QINIU_ACCESS_KEY, MediaServerConfig.QINIU_SECRET_KEY);
|
||||
String token = auth.uploadToken(bucketName, key);
|
||||
String downloadUrl = bucketDomain + "/" + key;
|
||||
String uploadUrl = "https://" + MediaServerConfig.QINIU_SERVER_URL + "?" + token + "?" + key;
|
||||
|
||||
OutputPresignedUploadUrl outputPresignedUploadUrl = new OutputPresignedUploadUrl();
|
||||
outputPresignedUploadUrl.uploadUrl = uploadUrl;
|
||||
outputPresignedUploadUrl.downloadUrl = downloadUrl;
|
||||
outputPresignedUploadUrl.type = 1;
|
||||
setResponseContent(RestResult.ok(outputPresignedUploadUrl), response);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,39 @@ public class GetUserAction extends RobotAction {
|
||||
if (user == null || user.getDeleted() > 0) {
|
||||
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
|
||||
} else {
|
||||
result = RestResult.ok(InputOutputUserInfo.fromPbUser(user));
|
||||
InputOutputUserInfo outputUserInfo = InputOutputUserInfo.fromPbUser(user);
|
||||
int mask = messagesStore.getRobotGetUserInfoMask();
|
||||
if((mask & 1) == 0) {
|
||||
outputUserInfo.setName(null);
|
||||
}
|
||||
if((mask & 2) == 0) {
|
||||
outputUserInfo.setMobile(null);
|
||||
}
|
||||
if((mask & 4) == 0) {
|
||||
outputUserInfo.setEmail(null);
|
||||
}
|
||||
if((mask & 8) == 0) {
|
||||
outputUserInfo.setAddress(null);
|
||||
}
|
||||
if((mask & 16) == 0) {
|
||||
outputUserInfo.setCompany(null);
|
||||
}
|
||||
if((mask & 32) == 0) {
|
||||
outputUserInfo.setExtra(null);
|
||||
}
|
||||
if((mask & 64) == 0) {
|
||||
outputUserInfo.setUpdateDt(0);
|
||||
}
|
||||
if((mask & 128) == 0) {
|
||||
outputUserInfo.setGender(0);
|
||||
}
|
||||
if((mask & 256) == 0) {
|
||||
outputUserInfo.setSocial(null);
|
||||
}
|
||||
if((mask & 512) == 0) {
|
||||
outputUserInfo.setType(0);
|
||||
}
|
||||
result = RestResult.ok(outputUserInfo);
|
||||
}
|
||||
setResponseContent(result, response);
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.robot;
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
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.Robot_User_Get_Email_Info)
|
||||
@HttpMethod("POST")
|
||||
public class GetUsersByEmailAction extends RobotAction {
|
||||
|
||||
@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<>();
|
||||
int mask = messagesStore.getRobotGetUserInfoMask();
|
||||
for (WFCMessage.User user : users) {
|
||||
InputOutputUserInfo outputUserInfo = InputOutputUserInfo.fromPbUser(user);
|
||||
if((mask & 1) == 0) {
|
||||
outputUserInfo.setName(null);
|
||||
}
|
||||
if((mask & 2) == 0) {
|
||||
outputUserInfo.setMobile(null);
|
||||
}
|
||||
if((mask & 4) == 0) {
|
||||
outputUserInfo.setEmail(null);
|
||||
}
|
||||
if((mask & 8) == 0) {
|
||||
outputUserInfo.setAddress(null);
|
||||
}
|
||||
if((mask & 16) == 0) {
|
||||
outputUserInfo.setCompany(null);
|
||||
}
|
||||
if((mask & 32) == 0) {
|
||||
outputUserInfo.setExtra(null);
|
||||
}
|
||||
if((mask & 64) == 0) {
|
||||
outputUserInfo.setUpdateDt(0);
|
||||
}
|
||||
if((mask & 128) == 0) {
|
||||
outputUserInfo.setGender(0);
|
||||
}
|
||||
if((mask & 256) == 0) {
|
||||
outputUserInfo.setSocial(null);
|
||||
}
|
||||
if((mask & 512) == 0) {
|
||||
outputUserInfo.setType(0);
|
||||
}
|
||||
list.add(outputUserInfo);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package com.xiaoleilu.loServer.action.robot;
|
||||
|
||||
|
||||
import cn.wildfirechat.common.APIPath;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.Conversation;
|
||||
import cn.wildfirechat.pojos.ReplyMessageData;
|
||||
import cn.wildfirechat.pojos.SendMessageData;
|
||||
import cn.wildfirechat.pojos.SendMessageResult;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
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.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Route(APIPath.Robot_Message_Reply)
|
||||
@HttpMethod("POST")
|
||||
public class ReplyMessageAction extends RobotAction {
|
||||
|
||||
@Override
|
||||
public boolean isTransactionAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean action(Request request, Response response) {
|
||||
if (request.getNettyRequest() instanceof FullHttpRequest) {
|
||||
ReplyMessageData replyMessageData = getRequestBody(request.getNettyRequest(), ReplyMessageData.class);
|
||||
if (ReplyMessageData.isValide(replyMessageData)) {
|
||||
WFCMessage.Message message = messagesStore.getMessage(replyMessageData.getMessageUid());
|
||||
ErrorCode errorCode = null;
|
||||
if(message == null) {
|
||||
errorCode = ErrorCode.ERROR_CODE_NOT_EXIST;
|
||||
} else if(!message.getContent().getMentionedTargetList().contains(robot.getUid())) {
|
||||
errorCode = ErrorCode.ERROR_CODE_INVALID_MESSAGE;
|
||||
} else if(message.getConversation().getType() != ProtoConstants.ConversationType.ConversationType_Private && message.getConversation().getType() != ProtoConstants.ConversationType.ConversationType_Group) {
|
||||
errorCode = ErrorCode.ERROR_CODE_NOT_IMPLEMENT;
|
||||
} else if(System.currentTimeMillis() - message.getServerTimestamp() > 15*60*1000) {
|
||||
errorCode = ErrorCode.ERROR_CODE_RECALL_TIME_EXPIRED;
|
||||
} else if(!messagesStore.isRobotMentionExternalRobot()) {
|
||||
if(message.getConversation().getType() != ProtoConstants.ConversationType.ConversationType_Group) {
|
||||
errorCode = ErrorCode.ERROR_CODE_NOT_IMPLEMENT;
|
||||
} else {
|
||||
WFCMessage.GroupMember member = messagesStore.getGroupMember(message.getConversation().getTarget(), robot.getUid());
|
||||
if(member == null || member.getType() == ProtoConstants.GroupMemberType.GroupMemberType_Removed) {
|
||||
errorCode = ErrorCode.ERROR_CODE_NOT_IMPLEMENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(errorCode != null) {
|
||||
response.setStatus(HttpResponseStatus.OK);
|
||||
RestResult result = RestResult.resultOf(errorCode);
|
||||
response.setContent(gson.toJson(result));
|
||||
return true;
|
||||
}
|
||||
|
||||
SendMessageData sendMessageData = getSendMessageData(message, replyMessageData);
|
||||
WFCMessage.Message newMsg = sendMessageData.toProtoMessage().toBuilder().setMessageId(message.getMessageId()).build();
|
||||
sendApiRequest(response, IMTopic.RobotReplyMessageTopic, newMsg.toByteArray(), result -> {
|
||||
ByteBuf byteBuf = Unpooled.buffer();
|
||||
byteBuf.writeBytes(result);
|
||||
ErrorCode ec = ErrorCode.fromCode(byteBuf.readByte());
|
||||
if (ec == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
long messageId = byteBuf.readLong();
|
||||
long timestamp = byteBuf.readLong();
|
||||
sendResponse(response, null, new SendMessageResult(messageId, timestamp));
|
||||
} else {
|
||||
sendResponse(response, ec, null);
|
||||
}
|
||||
});
|
||||
return false;
|
||||
} else {
|
||||
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private @NotNull SendMessageData getSendMessageData(WFCMessage.Message message, ReplyMessageData replyMessageData) {
|
||||
SendMessageData sendMessageData = new SendMessageData();
|
||||
sendMessageData.setSender(robot.getUid());
|
||||
Conversation conversation = new Conversation();
|
||||
conversation.setType(message.getConversation().getType());
|
||||
conversation.setLine(message.getConversation().getLine());
|
||||
conversation.setTarget(message.getConversation().getTarget());
|
||||
sendMessageData.setConv(conversation);
|
||||
sendMessageData.setPayload(replyMessageData.getPayload());
|
||||
if(replyMessageData.isOnly2Sender()) {
|
||||
sendMessageData.setToUsers(Arrays.asList(message.getFromUser()));
|
||||
}
|
||||
return sendMessageData;
|
||||
}
|
||||
}
|
||||
@@ -106,24 +106,6 @@ abstract public class RobotAction extends Action {
|
||||
response.send();
|
||||
}
|
||||
|
||||
protected <T> T getRequestBody(HttpRequest request, Class<T> cls) {
|
||||
if (request instanceof FullHttpRequest) {
|
||||
FullHttpRequest fullHttpRequest = (FullHttpRequest) request;
|
||||
byte[] bytes = Utils.readBytesAndRewind(fullHttpRequest.content());
|
||||
String content = null;
|
||||
try {
|
||||
content = new String(bytes, "UTF-8");
|
||||
|
||||
T t = gson.fromJson(content, cls);
|
||||
return t;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ROBOT_API_Exception);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void sendApiRequest(Response response, String topic, byte[] message, Callback callback) {
|
||||
ServerAPIHelper.sendRequest(robot.getUid(), null, topic, message, new ServerAPIHelper.Callback() {
|
||||
@Override
|
||||
|
||||
@@ -82,6 +82,15 @@ public final class BrokerConstants {
|
||||
public static final String QINIU_BUCKET_PORTRAIT_DOMAIN = "qiniu.bucket_portrait_domain";
|
||||
public static final String QINIU_BUCKET_FAVORITE_NAME= "qiniu.bucket_favorite_name";
|
||||
public static final String QINIU_BUCKET_FAVORITE_DOMAIN = "qiniu.bucket_favorite_domain";
|
||||
public static final String QINIU_BUCKET_CUSTOM1_NAME= "qiniu.bucket_custom1_name";
|
||||
public static final String QINIU_BUCKET_CUSTOM1_DOMAIN = "qiniu.bucket_custom1_domain";
|
||||
public static final String QINIU_BUCKET_CUSTOM2_NAME= "qiniu.bucket_custom2_name";
|
||||
public static final String QINIU_BUCKET_CUSTOM2_DOMAIN = "qiniu.bucket_custom2_domain";
|
||||
public static final String QINIU_BUCKET_CUSTOM3_NAME= "qiniu.bucket_custom3_name";
|
||||
public static final String QINIU_BUCKET_CUSTOM3_DOMAIN = "qiniu.bucket_custom3_domain";
|
||||
public static final String QINIU_BUCKET_PAN_NAME= "qiniu.bucket_pan_name";
|
||||
public static final String QINIU_BUCKET_PAN_DOMAIN = "qiniu.bucket_pan_domain";
|
||||
|
||||
|
||||
public static final String FILE_STORAGE_ROOT = "local.media.storage.root";
|
||||
public static final String FILE_STORAGE_REMOTE_SERVER_URL = "local.media.storage.remote_server_url";
|
||||
@@ -124,7 +133,7 @@ public final class BrokerConstants {
|
||||
|
||||
|
||||
public static final String SENSITIVE_Filter_Type = "sensitive.filter.type";
|
||||
|
||||
public static final String SENSITIVE_Only_Message = "sensitive.only_message";
|
||||
public static final String SENSITIVE_Remote_Server_URL = "sensitive.remote_server_url";
|
||||
public static final String SENSITIVE_Remote_Message_Type = "sensitive.remote_sensitive_message_type";
|
||||
public static final String SENSITIVE_Remote_Fail_When_Matched = "sensitive.remote_fail_when_matched";
|
||||
@@ -139,6 +148,8 @@ public final class BrokerConstants {
|
||||
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_PAD_ENDPOINT = "server.multi_pad_endpoint";
|
||||
public static final String SERVER_MULTI_WEARABLE_ENDPOINT = "server.multi_wearable_endpoint";
|
||||
public static final String SERVER_MULTI_TV_ENDPOINT = "server.multi_tv_endpoint";
|
||||
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_CLIENT_SUPPORT_KICKOFF_EVENT = "server.client_support_kickoff_event";
|
||||
@@ -163,11 +174,22 @@ public final class BrokerConstants {
|
||||
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_Sender_Info = "message.forward_with_sender_info";
|
||||
public static final String MESSAGE_Forward_With_Target_Info = "message.forward_with_target_info";
|
||||
|
||||
public static final String BROADCAST_Target_From_User_Table = "message.broadcast.target_from_user_table";
|
||||
|
||||
public static final String MESSAGES_ALLOW_SEND_TO_FORBIDDEN_USER = "message.allow_send_to_forbidden_user";
|
||||
|
||||
public static final String ROBOT_Callback_With_Client_Info = "robot.callback_with_client_info";
|
||||
public static final String ROBOT_Callback_With_Sender_Info = "robot.callback_with_sender_info";
|
||||
public static final String ROBOT_Callback_With_Target_Info = "robot.callback_with_target_info";
|
||||
public static final String ROBOT_Mention_External_Robot = "robot.mention_external_robot";
|
||||
public static final String ROBOT_Get_User_Info_Mask = "robot.get_user_info_mask";
|
||||
|
||||
public static final String CHANNEL_Callback_With_Client_Info = "channel.callback_with_client_info";
|
||||
public static final String CHANNEL_Callback_With_Sender_Info = "channel.callback_with_sender_info";
|
||||
public static final String CHANNEL_Callback_With_Target_Info = "channel.callback_with_target_info";
|
||||
public static final String CHANNEL_New_Callback_Feature = "channel.new_callback_feature";
|
||||
|
||||
|
||||
@@ -179,6 +201,8 @@ public final class BrokerConstants {
|
||||
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_Rate_Limit = "friend.request_rate_limit";
|
||||
public static final String FRIEND_Search_Mobile_Empty_Rate_Limit = "friend.search_mobile_empty_rate_limit";
|
||||
public static final String FRIEND_Search_Rate_Limit = "friend.search_rate_limit";
|
||||
public static final String FRIEND_Request_Robot_Auto_Accept = "friend.robot_auto_accept";
|
||||
|
||||
|
||||
@@ -196,11 +220,15 @@ public final class BrokerConstants {
|
||||
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_ADD_MEMBER_ALLOW_PART_SUCCESS = "group.add_member_allow_part_success";
|
||||
|
||||
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_KEEP_DISPLAY_NAME_WHEN_DESTROY = "user.keep_display_name_when_destroy";
|
||||
public static final String USER_KEEP_FULL_INFO_WHEN_DESTROY = "user.keep_full_info_when_destroy";
|
||||
public static final String USER_KEEP_MOBILE_WHEN_DESTROY = "user.keep_mobile_when_destroy";
|
||||
public static final String USER_KEEP_MESSAGES_WHEN_DESTROY = "user.keep_messages_when_destroy";
|
||||
|
||||
public static final String SYNC_Data_Part_Size = "sync.data_part_size";
|
||||
|
||||
|
||||
@@ -16,6 +16,10 @@ import io.netty.buffer.ByteBuf;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
|
||||
|
||||
@Handler(value = IMTopic.AddGroupMemberTopic)
|
||||
@@ -38,16 +42,34 @@ public class AddGroupMember extends GroupHandler<WFCMessage.AddGroupMemberReques
|
||||
}
|
||||
}
|
||||
|
||||
ErrorCode errorCode = m_messagesStore.addGroupMembers(fromUser, isAdmin, request.getGroupId(), request.getAddedMemberList(), request.getExtra());
|
||||
Map<String, Integer> failedMembers = new HashMap<>();
|
||||
if(requestSourceType == ProtoConstants.RequestSourceType.Request_From_User) {
|
||||
ErrorCode errorCode = m_messagesStore.canAddGroupMembers(fromUser, request.getAddedMemberList(), failedMembers);
|
||||
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
|
||||
ErrorCode errorCode = m_messagesStore.addGroupMembers(fromUser, isAdmin, request.getGroupId(), request.getAddedMemberList(), request.getExtra(), failedMembers);
|
||||
if (errorCode == ERROR_CODE_SUCCESS) {
|
||||
if (request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), request.getNotifyContent());
|
||||
} else {
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, getMemberIdList(request.getAddedMemberList())).setExtra(request.getExtra()).getAddGroupNotifyContent();
|
||||
List<String> added = getMemberIdList(request.getAddedMemberList());
|
||||
added.removeAll(failedMembers.keySet());
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, added).setExtra(request.getExtra()).getAddGroupNotifyContent();
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content);
|
||||
}
|
||||
}
|
||||
|
||||
if (errorCode == ERROR_CODE_SUCCESS && !failedMembers.isEmpty()) {
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(request.getGroupId(), fromUser, null, "").setMi(failedMembers).getGroupNotifyContent(ProtoConstants.MESSAGE_CONTENT_TYPE_REJECT_JOIN_GROUP);
|
||||
sendGroupNotification(fromUser, request.getGroupId(), request.getToLineList(), content);
|
||||
}
|
||||
|
||||
if(errorCode == ERROR_CODE_SUCCESS && !failedMembers.isEmpty()) {
|
||||
return ErrorCode.ERROR_CODE_PARTLY_SUCCESS;
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import io.netty.buffer.ByteBuf;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import static cn.wildfirechat.proto.ProtoConstants.RequestSourceType.Request_From_Admin;
|
||||
import static win.liyufan.im.IMTopic.PutUserSettingTopic;
|
||||
import static win.liyufan.im.UserSettingScope.kUserSettingMyChannels;
|
||||
|
||||
@@ -42,7 +43,13 @@ public class CreateChannelHandler extends GroupHandler<WFCMessage.ChannelInfo> {
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
WFCMessage.ModifyUserSettingReq modifyUserSettingReq = WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingMyChannels).setKey(request.getTargetId()).setValue("1").build();
|
||||
mServer.onApiMessage(fromUser, null, modifyUserSettingReq.toByteArray(), 0, fromUser, PutUserSettingTopic, requestSourceType);
|
||||
byte[] data = request.getTargetId().getBytes();
|
||||
byte[] data;
|
||||
if (requestSourceType == Request_From_Admin) {
|
||||
//When server api create channel, need return channelId and secret together.
|
||||
data = (request.getTargetId() + "|" + request.getSecret()).getBytes();
|
||||
} else {
|
||||
data = request.getTargetId().getBytes();
|
||||
}
|
||||
ackPayload.ensureWritable(data.length).writeBytes(data);
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
} else {
|
||||
|
||||
@@ -17,6 +17,10 @@ import io.netty.buffer.ByteBuf;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Handler(value = IMTopic.CreateGroupTopic)
|
||||
public class CreateGroupHandler extends GroupHandler<WFCMessage.CreateGroupRequest> {
|
||||
@Override
|
||||
@@ -51,14 +55,34 @@ public class CreateGroupHandler extends GroupHandler<WFCMessage.CreateGroupReque
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Integer> failedMembers = new HashMap<>();
|
||||
if(requestSourceType == ProtoConstants.RequestSourceType.Request_From_User) {
|
||||
ErrorCode errorCode = m_messagesStore.canAddGroupMembers(fromUser, request.getGroup().getMembersList());
|
||||
ErrorCode errorCode = m_messagesStore.canAddGroupMembers(fromUser, request.getGroup().getMembersList(), failedMembers);
|
||||
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
|
||||
WFCMessage.GroupInfo groupInfo = m_messagesStore.createGroup(fromUser, request.getGroup().getGroupInfo(), request.getGroup().getMembersList(), request.getMemberExtra(), isAdmin);
|
||||
if (request.getGroup().getGroupInfo().getTargetId().length() > 64
|
||||
|| request.getGroup().getGroupInfo().getName().length() > 64
|
||||
|| request.getGroup().getGroupInfo().getPortrait().length() > 1024) {
|
||||
return ErrorCode.INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if(!isAdmin && !StringUtil.isNullOrEmpty(request.getGroup().getGroupInfo().getName())) {
|
||||
if(!m_messagesStore.isSensitiveOnlyMessage()) {
|
||||
Set<String> matched = m_messagesStore.handleSensitiveWord(request.getGroup().getGroupInfo().getName());
|
||||
if (matched != null && !matched.isEmpty()) {
|
||||
return ErrorCode.ERROR_CODE_SENSITIVE_MATCHED;
|
||||
}
|
||||
}
|
||||
|
||||
if(!m_messagesStore.isAllowName(request.getGroup().getGroupInfo().getName())) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
WFCMessage.GroupInfo groupInfo = m_messagesStore.createGroup(fromUser, request.getGroup().getGroupInfo(), request.getGroup().getMembersList(), request.getMemberExtra(), isAdmin, failedMembers);
|
||||
if (groupInfo != null && groupInfo.getDeleted() == 0) {
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0) {
|
||||
sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), request.getNotifyContent());
|
||||
@@ -66,9 +90,19 @@ public class CreateGroupHandler extends GroupHandler<WFCMessage.CreateGroupReque
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(groupInfo.getTargetId(), fromUser, groupInfo.getName(), "").setExtra(request.getMemberExtra()).getCreateGroupNotifyContent();
|
||||
sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), content);
|
||||
}
|
||||
|
||||
if(!failedMembers.isEmpty()) {
|
||||
WFCMessage.MessageContent content = new GroupNotificationBinaryContent(groupInfo.getTargetId(), fromUser, null, "").setMi(failedMembers).getGroupNotifyContent(ProtoConstants.MESSAGE_CONTENT_TYPE_REJECT_JOIN_GROUP);
|
||||
sendGroupNotification(fromUser, groupInfo.getTargetId(), request.getToLineList(), content);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] data = groupInfo.getTargetId().getBytes();
|
||||
ackPayload.ensureWritable(data.length).writeBytes(data);
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
if(failedMembers.isEmpty()) {
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
} else {
|
||||
return ErrorCode.ERROR_CODE_PARTLY_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ public class GetMediaUploadTokenHandler extends IMHandler<WFCMessage.GetUploadTo
|
||||
if (MediaServerConfig.USER_QINIU) {
|
||||
Auth auth = Auth.create(MediaServerConfig.QINIU_ACCESS_KEY, MediaServerConfig.QINIU_SECRET_KEY);
|
||||
|
||||
|
||||
String bucketName;
|
||||
String bucketDomain;
|
||||
switch (type) {
|
||||
@@ -72,6 +71,22 @@ public class GetMediaUploadTokenHandler extends IMHandler<WFCMessage.GetUploadTo
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_MOMENTS_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_MOMENTS_DOMAIN;
|
||||
break;
|
||||
case 9:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM1_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM1_DOMAIN;
|
||||
break;
|
||||
case 10:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM2_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM2_DOMAIN;
|
||||
break;
|
||||
case 11:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM3_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM3_DOMAIN;
|
||||
break;
|
||||
case 12:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_PAN_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_PAN_DOMAIN;
|
||||
break;
|
||||
default:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_GENERAL_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_GENERAL_DOMAIN;
|
||||
|
||||
@@ -77,6 +77,22 @@ public class GetQiniuUploadTokenHandler extends IMHandler<Byte> {
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_MOMENTS_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_MOMENTS_DOMAIN;
|
||||
break;
|
||||
case 9:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM1_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM1_DOMAIN;
|
||||
break;
|
||||
case 10:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM2_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM2_DOMAIN;
|
||||
break;
|
||||
case 11:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_CUSTOM3_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_CUSTOM3_DOMAIN;
|
||||
break;
|
||||
case 12:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_PAN_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_PAN_DOMAIN;
|
||||
break;
|
||||
default:
|
||||
bucketName = MediaServerConfig.QINIU_BUCKET_GENERAL_NAME;
|
||||
bucketDomain = MediaServerConfig.QINIU_BUCKET_GENERAL_DOMAIN;
|
||||
|
||||
@@ -16,6 +16,7 @@ import io.moquette.spi.impl.security.TokenAuthenticator;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.IMTopic;
|
||||
import win.liyufan.im.UserSettingScope;
|
||||
|
||||
@Handler(IMTopic.GetTokenTopic)
|
||||
public class GetTokenHandler extends IMHandler<WFCMessage.GetTokenRequest> {
|
||||
@@ -26,6 +27,11 @@ public class GetTokenHandler extends IMHandler<WFCMessage.GetTokenRequest> {
|
||||
if(userInfo != null && userInfo.getType() == 1) {
|
||||
return ErrorCode.ERROR_CODE_ROBOT_NO_TOKEN;
|
||||
}
|
||||
if(session.isPcClient() || session.isPadClient() || session.isTVClient()) {
|
||||
if(m_messagesStore.isLocked(session.getUsername(), session.getClientID())) {
|
||||
m_messagesStore.updateUserSettings(session.getUsername(), WFCMessage.ModifyUserSettingReq.newBuilder().setScope(UserSettingScope.UserSettingScopeLockPC).setKey(session.getClientID()).setValue("0").build(), null);
|
||||
}
|
||||
}
|
||||
|
||||
TokenAuthenticator authenticator = new TokenAuthenticator();
|
||||
String strToken = authenticator.generateToken(fromUser);
|
||||
|
||||
@@ -45,20 +45,20 @@ public class HandleFriendRequestHandler extends IMHandler<WFCMessage.HandleFrien
|
||||
contentBuilder.setType(92);
|
||||
|
||||
builder = WFCMessage.Message.newBuilder();
|
||||
builder.setFromUser(request.getTargetUid());
|
||||
builder.setConversation(WFCMessage.Conversation.newBuilder().setTarget(fromUser).setLine(0).setType(ProtoConstants.ConversationType.ConversationType_Private).build());
|
||||
builder.setFromUser(fromUser);
|
||||
builder.setConversation(WFCMessage.Conversation.newBuilder().setTarget(request.getTargetUid()).setLine(0).setType(ProtoConstants.ConversationType.ConversationType_Private).build());
|
||||
builder.setContent(contentBuilder);
|
||||
builder.setServerTimestamp(++timestamp);
|
||||
|
||||
messageId = MessageShardingUtil.generateId();
|
||||
builder.setMessageId(messageId);
|
||||
saveAndPublish(request.getTargetUid(), null, builder.build(), requestSourceType);
|
||||
saveAndPublish(fromUser, null, builder.build(), requestSourceType);
|
||||
contentBuilder.setType(93);
|
||||
builder.setContent(contentBuilder);
|
||||
messageId = MessageShardingUtil.generateId();
|
||||
builder.setMessageId(messageId);
|
||||
builder.setServerTimestamp(++timestamp);
|
||||
saveAndPublish(request.getTargetUid(), null, builder.build(), requestSourceType);
|
||||
saveAndPublish(fromUser, null, builder.build(), requestSourceType);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -11,11 +11,14 @@ package io.moquette.imhandler;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import cn.wildfirechat.pojos.GroupNotificationBinaryContent;
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import io.moquette.spi.impl.Qos1PublishHandler;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
|
||||
|
||||
@Handler(IMTopic.ModifyGroupAliasTopic)
|
||||
@@ -26,10 +29,24 @@ public class ModifyGroupAliasHandler extends GroupHandler<WFCMessage.ModifyGroup
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && requestSourceType == ProtoConstants.RequestSourceType.Request_From_User && !m_messagesStore.isAllowClientCustomGroupNotification()) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && requestSourceType == ProtoConstants.RequestSourceType.Request_From_Robot && !m_messagesStore.isAllowRobotCustomGroupNotification()) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
if (!isAdmin && !StringUtil.isNullOrEmpty(request.getAlias())) {
|
||||
if(!m_messagesStore.isSensitiveOnlyMessage()) {
|
||||
Set<String> matched = m_messagesStore.handleSensitiveWord(request.getAlias());
|
||||
if (matched != null && !matched.isEmpty()) {
|
||||
return ErrorCode.ERROR_CODE_SENSITIVE_MATCHED;
|
||||
}
|
||||
}
|
||||
|
||||
if(!m_messagesStore.isAllowName(request.getAlias())) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
ErrorCode errorCode = m_messagesStore.modifyGroupMemberAlias(fromUser, request.getGroupId(), request.getAlias(), null, isAdmin);
|
||||
if (errorCode == ERROR_CODE_SUCCESS) {
|
||||
if (request.hasNotifyContent()&& request.getNotifyContent().getType() > 0) {
|
||||
|
||||
@@ -12,10 +12,13 @@ import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.GroupNotificationBinaryContent;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import io.moquette.spi.impl.Qos1PublishHandler;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
|
||||
|
||||
@Handler(IMTopic.ModifyGroupMemberAliasTopic)
|
||||
@@ -29,6 +32,18 @@ public class ModifyGroupMemberAliasHandler extends GroupHandler<WFCMessage.Modif
|
||||
if(request.hasNotifyContent() && request.getNotifyContent().getType() > 0 && requestSourceType == ProtoConstants.RequestSourceType.Request_From_Robot && !m_messagesStore.isAllowRobotCustomGroupNotification()) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
if (!isAdmin && !StringUtil.isNullOrEmpty(request.getAlias())) {
|
||||
if(!m_messagesStore.isSensitiveOnlyMessage()) {
|
||||
Set<String> matched = m_messagesStore.handleSensitiveWord(request.getAlias());
|
||||
if (matched != null && !matched.isEmpty()) {
|
||||
return ErrorCode.ERROR_CODE_SENSITIVE_MATCHED;
|
||||
}
|
||||
}
|
||||
|
||||
if(!m_messagesStore.isAllowName(request.getAlias())) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
ErrorCode errorCode = m_messagesStore.modifyGroupMemberAlias(fromUser, request.getGroupId(), request.getAlias(), request.getMemberId(), isAdmin);
|
||||
if (errorCode == ERROR_CODE_SUCCESS) {
|
||||
|
||||
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
* This file is part of the Wildfire Chat package.
|
||||
* (c) Heavyrain2012 <[email protected]>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
package io.moquette.imhandler;
|
||||
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.pojos.MessagePayload;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import io.moquette.BrokerConstants;
|
||||
import io.moquette.spi.impl.Qos1PublishHandler;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import win.liyufan.im.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_NOT_IN_GROUP;
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
|
||||
|
||||
@Handler(value = IMTopic.RobotReplyMessageTopic)
|
||||
public class ReplyMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
private int mSensitiveType = 0; //命中敏感词时,0 失败,1 吞掉, 2 敏感词替换成*。
|
||||
private String mForwardUrl = null;
|
||||
private String mSensitiveMessageForwardUrl = null;
|
||||
private Set<Integer> mForwardMessageTypes = new HashSet<>();
|
||||
private Set<Integer> mForwardExcludeMessageTypes = new HashSet<>();
|
||||
private String mMentionForwardUrl = null;
|
||||
private int mBlacklistStrategy = 0; //黑名单中时,0失败,1吞掉。
|
||||
private boolean mBlacklistAllowSend2Black = true;
|
||||
private boolean mNoForwardAdminMessage = false;
|
||||
private boolean mAllowSend2ForbiddenUser = false;
|
||||
|
||||
private String mRemoteSensitiveServerUrl = null;
|
||||
private Set<Integer> mRemoteSensitiveMessageTypes;
|
||||
private boolean mWaitRemoteSensitiveServerResponse = false;
|
||||
|
||||
public ReplyMessageHandler() {
|
||||
super();
|
||||
|
||||
mForwardUrl = mServer.getConfig().getProperty(BrokerConstants.MESSAGE_Forward_Url);
|
||||
if (!StringUtil.isNullOrEmpty(mForwardUrl)) {
|
||||
String forwardTypes = mServer.getConfig().getProperty(BrokerConstants.MESSAGE_Forward_Types);
|
||||
parseTypes(mForwardMessageTypes, forwardTypes);
|
||||
String excludeTypes = mServer.getConfig().getProperty(BrokerConstants.MESSAGE_Forward_Exclude_Types);
|
||||
parseTypes(mForwardExcludeMessageTypes, excludeTypes);
|
||||
}
|
||||
mSensitiveMessageForwardUrl = mServer.getConfig().getProperty(BrokerConstants.MESSAGE_Sensitive_Forward_Url);
|
||||
mMentionForwardUrl = mServer.getConfig().getProperty(BrokerConstants.MESSAGE_MentionMsg_Forward_Url);
|
||||
|
||||
try {
|
||||
mSensitiveType = Integer.parseInt(mServer.getConfig().getProperty(BrokerConstants.SENSITIVE_Filter_Type));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
|
||||
try {
|
||||
mBlacklistStrategy = Integer.parseInt(mServer.getConfig().getProperty(BrokerConstants.MESSAGE_Blacklist_Strategy));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
|
||||
try {
|
||||
mBlacklistAllowSend2Black = Boolean.parseBoolean(mServer.getConfig().getProperty(BrokerConstants.MESSAGE_Blacklist_Allow_Send, "true"));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
try {
|
||||
mRemoteSensitiveServerUrl = mServer.getConfig().getProperty(BrokerConstants.SENSITIVE_Remote_Server_URL);
|
||||
if(!StringUtil.isNullOrEmpty(mRemoteSensitiveServerUrl)) {
|
||||
mWaitRemoteSensitiveServerResponse = Boolean.parseBoolean(mServer.getConfig().getProperty(BrokerConstants.SENSITIVE_Remote_Fail_When_Matched, "false"));
|
||||
String types = mServer.getConfig().getProperty(BrokerConstants.SENSITIVE_Remote_Message_Type, "");
|
||||
mRemoteSensitiveMessageTypes = new HashSet<>();
|
||||
if(!StringUtil.isNullOrEmpty(types)) {
|
||||
String[] ts = types.split(",");
|
||||
for (String t:ts) {
|
||||
mRemoteSensitiveMessageTypes.add(Integer.parseInt(t.trim()));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
|
||||
try {
|
||||
mNoForwardAdminMessage = Boolean.parseBoolean(mServer.getConfig().getProperty(BrokerConstants.MESSAGE_NO_Forward_Admin_Message, "false"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
|
||||
try {
|
||||
mAllowSend2ForbiddenUser = Boolean.parseBoolean(mServer.getConfig().getProperty(BrokerConstants.MESSAGES_ALLOW_SEND_TO_FORBIDDEN_USER, "false"));
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
private void parseTypes(Collection<Integer> collection, String types) {
|
||||
try {
|
||||
if (!StringUtil.isNullOrEmpty(types)) {
|
||||
String[] tss = types.split(",");
|
||||
for (String ts:tss) {
|
||||
if(ts.contains("-")) {
|
||||
String[] ss = ts.split("-");
|
||||
if(ss.length == 2) {
|
||||
int begin = Integer.parseInt(ss[0]);
|
||||
int end = Integer.parseInt(ss[1]);
|
||||
for (int i = begin; i <= end ; i++) {
|
||||
collection.add(i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
collection.add(Integer.parseInt(ts.trim()));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.Message message, Qos1PublishHandler.IMCallback callback) {
|
||||
if(requestSourceType != ProtoConstants.RequestSourceType.Request_From_Robot) {
|
||||
return ErrorCode.ERROR_CODE_NOT_IMPLEMENT;
|
||||
}
|
||||
|
||||
ErrorCode errorCode = ErrorCode.ERROR_CODE_SUCCESS;
|
||||
|
||||
if (message != null) {
|
||||
if(message.getContent().getContent().length() +
|
||||
message.getContent().getSearchableContent().length() +
|
||||
message.getContent().getData().size() +
|
||||
message.getContent().getExtra().length() +
|
||||
message.getContent().getPushContent().length() +
|
||||
message.getContent().getPushData().length() > 64 * 1024) {
|
||||
return ErrorCode.ERROR_CODE_MESSAGE_TOO_LARGE;
|
||||
}
|
||||
|
||||
boolean ignoreMsg = false;
|
||||
|
||||
// 不能在端上直接发送撤回和群通知
|
||||
if (message.getContent().getType() == 80 || message.getContent().getType() == 81 || (message.getContent().getType() >= 100 && message.getContent().getType() < 200)) {
|
||||
return ErrorCode.INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if(m_messagesStore.getClientForbiddenSendTypes().contains(message.getContent().getType())) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
int userStatus = m_messagesStore.getUserStatus(fromUser);
|
||||
if (userStatus == ProtoConstants.UserStatus.Muted || userStatus == ProtoConstants.UserStatus.Forbidden) {
|
||||
if(!m_messagesStore.getGlobalMuteExceptionTypes().contains(message.getContent().getType())) {
|
||||
return ErrorCode.ERROR_CODE_FORBIDDEN_SEND_MSG;
|
||||
}
|
||||
}
|
||||
|
||||
if (message.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Private) {
|
||||
if(!m_messagesStore.getBlackListExceptionTypes().contains(message.getContent().getType())) {
|
||||
errorCode = m_messagesStore.isAllowUserMessage(message.getConversation().getTarget(), fromUser, message.getConversation().getLine());
|
||||
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
if (errorCode == ErrorCode.ERROR_CODE_IN_BLACK_LIST && mBlacklistStrategy != ProtoConstants.BlacklistStrategy.Message_Reject) {
|
||||
ignoreMsg = true;
|
||||
errorCode = ErrorCode.ERROR_CODE_SUCCESS;
|
||||
} else {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
|
||||
if(!mBlacklistAllowSend2Black) {
|
||||
errorCode = m_messagesStore.isBlacked(fromUser, message.getConversation().getTarget());
|
||||
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mAllowSend2ForbiddenUser) {
|
||||
userStatus = m_messagesStore.getUserStatus(message.getConversation().getTarget());
|
||||
if (userStatus == ProtoConstants.UserStatus.Forbidden) {
|
||||
return ErrorCode.ERROR_CODE_USER_FORBIDDEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (message.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Group ) {
|
||||
if(!m_messagesStore.getGroupMuteExceptionTypes().contains(message.getContent().getType())) {
|
||||
errorCode = m_messagesStore.canSendMessageInGroup(fromUser, message.getConversation().getTarget());
|
||||
if(errorCode == ERROR_CODE_NOT_IN_GROUP) {
|
||||
errorCode = ERROR_CODE_SUCCESS;
|
||||
}
|
||||
if (errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
} else if (message.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_ChatRoom) {
|
||||
if(!m_messagesStore.getGroupMuteExceptionTypes().contains(message.getContent().getType())) {
|
||||
if (!m_messagesStore.checkUserClientInChatroom(fromUser, clientID, message.getConversation().getTarget())) {
|
||||
return ErrorCode.ERROR_CODE_NOT_IN_CHATROOM;
|
||||
}
|
||||
}
|
||||
} else if (message.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Channel) {
|
||||
if(!m_messagesStore.getGroupMuteExceptionTypes().contains(message.getContent().getType())) {
|
||||
if (!m_messagesStore.canSendMessageInChannel(fromUser, message.getConversation().getTarget())) {
|
||||
return ErrorCode.ERROR_CODE_NOT_IN_CHANNEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(message.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Private) {
|
||||
long beforeMessageId = message.getMessageId();
|
||||
WFCMessage.Message replyMsg = m_messagesStore.getMessage(beforeMessageId);
|
||||
message = message.toBuilder().setConversation(message.getConversation().toBuilder().setTarget(replyMsg.getFromUser() + "|" + replyMsg.getConversation().getTarget())).build();
|
||||
}
|
||||
|
||||
long timestamp = System.currentTimeMillis();
|
||||
final long messageId;
|
||||
try {
|
||||
messageId = MessageShardingUtil.generateId();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return ErrorCode.ERROR_CODE_SERVER_ERROR;
|
||||
}
|
||||
message = message.toBuilder().setFromUser(fromUser).setMessageId(messageId).setServerTimestamp(timestamp).build();
|
||||
|
||||
|
||||
if (!StringUtil.isNullOrEmpty(mForwardUrl) && (mForwardMessageTypes.isEmpty() || mForwardMessageTypes.contains(message.getContent().getType())) && !mForwardExcludeMessageTypes.contains(message.getContent().getType())) {
|
||||
publisher.forwardMessage(message, mForwardUrl, clientID);
|
||||
}
|
||||
|
||||
if(!StringUtil.isNullOrEmpty(mMentionForwardUrl) && message.hasContent() && message.getContent().getMentionedType() != 0) {
|
||||
publisher.forwardMessage(message, mMentionForwardUrl, clientID);
|
||||
}
|
||||
|
||||
|
||||
if(StringUtil.isNullOrEmpty(mRemoteSensitiveServerUrl)) {
|
||||
Set<String> matched = m_messagesStore.handleSensitiveWord(message.getContent().getSearchableContent());
|
||||
if (matched != null && !matched.isEmpty()) {
|
||||
m_messagesStore.storeSensitiveMessage(message);
|
||||
if (!StringUtil.isNullOrEmpty(mSensitiveMessageForwardUrl)) {
|
||||
publisher.forwardMessage(message, mSensitiveMessageForwardUrl, clientID);
|
||||
}
|
||||
if (mSensitiveType == 0) {
|
||||
errorCode = ErrorCode.ERROR_CODE_SENSITIVE_MATCHED;
|
||||
} else if (mSensitiveType == 1) {
|
||||
ignoreMsg = true;
|
||||
} else if (mSensitiveType == 2) {
|
||||
String text = message.getContent().getSearchableContent();
|
||||
for (String word : matched) {
|
||||
text = text.replace(word, "***");
|
||||
}
|
||||
message = message.toBuilder().setContent(message.getContent().toBuilder().setSearchableContent(text).build()).build();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(mRemoteSensitiveMessageTypes.contains(message.getContent().getType())) {
|
||||
final WFCMessage.Message finalMsg = message;
|
||||
publisher.forwardMessageWithCallback(message, clientID, mRemoteSensitiveServerUrl, new HttpUtils.HttpCallback() {
|
||||
@Override
|
||||
public void onSuccess(String content) {
|
||||
if(StringUtil.isNullOrEmpty(content)) {
|
||||
saveAndPublish(fromUser, clientID, finalMsg, requestSourceType);
|
||||
} else {
|
||||
MessagePayload payload = GsonUtil.gson.fromJson(content, MessagePayload.class);
|
||||
if (payload != null && payload.getType() > 0) {
|
||||
WFCMessage.Message newMsg = finalMsg.toBuilder().setContent(payload.toProtoMessageContent()).build();
|
||||
saveAndPublish(fromUser, clientID, newMsg, requestSourceType);
|
||||
} else {
|
||||
LOG.error("Response content {} from censor is invalid payload, ignore response and send original message", content);
|
||||
saveAndPublish(fromUser, clientID, finalMsg, requestSourceType);
|
||||
}
|
||||
}
|
||||
if(mWaitRemoteSensitiveServerResponse) {
|
||||
ByteBuf ackPayload = Unpooled.buffer(21);
|
||||
ErrorCode errorCode = ERROR_CODE_SUCCESS;
|
||||
ackPayload.writeByte(errorCode.getCode());
|
||||
ackPayload.writeLong(messageId);
|
||||
ackPayload.writeLong(timestamp);
|
||||
callback.onIMHandled(ErrorCode.ERROR_CODE_SUCCESS, ackPayload);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(int statusCode, String errorMessage) {
|
||||
ByteBuf ackPayload = null;
|
||||
ErrorCode errorCode = ERROR_CODE_SUCCESS;
|
||||
if(statusCode == 403) {
|
||||
if(mWaitRemoteSensitiveServerResponse) {
|
||||
errorCode = ErrorCode.ERROR_CODE_SENSITIVE_MATCHED;
|
||||
ackPayload = Unpooled.buffer(1);
|
||||
ackPayload.writeByte(errorCode.getCode());
|
||||
}
|
||||
} else {
|
||||
LOG.warn("Failed to censor message with status {}, errorMessage {}. Send the original message", statusCode, errorMessage);
|
||||
saveAndPublish(fromUser, clientID, finalMsg, requestSourceType);
|
||||
|
||||
if(mWaitRemoteSensitiveServerResponse) {
|
||||
errorCode = ERROR_CODE_SUCCESS;
|
||||
ackPayload = Unpooled.buffer(21);
|
||||
ackPayload.writeByte(errorCode.getCode());
|
||||
ackPayload.writeLong(messageId);
|
||||
ackPayload.writeLong(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
if(mWaitRemoteSensitiveServerResponse) {
|
||||
callback.onIMHandled(errorCode, ackPayload);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(mWaitRemoteSensitiveServerResponse) {
|
||||
ackPayload.clear();
|
||||
return ErrorCode.INVALID_ASYNC_HANDLING;
|
||||
} else {
|
||||
ackPayload = ackPayload.capacity(20);
|
||||
ackPayload.writeLong(messageId);
|
||||
ackPayload.writeLong(timestamp);
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
if(!ignoreMsg) {
|
||||
saveAndPublish(fromUser, clientID, message, requestSourceType);
|
||||
}
|
||||
ackPayload = ackPayload.capacity(20);
|
||||
ackPayload.writeLong(messageId);
|
||||
ackPayload.writeLong(timestamp);
|
||||
}
|
||||
} else {
|
||||
errorCode = ErrorCode.ERROR_CODE_INVALID_MESSAGE;
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,6 +39,7 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
private int mBlacklistStrategy = 0; //黑名单中时,0失败,1吞掉。
|
||||
private boolean mBlacklistAllowSend2Black = true;
|
||||
private boolean mNoForwardAdminMessage = false;
|
||||
private boolean mAllowSend2ForbiddenUser = false;
|
||||
|
||||
private String mRemoteSensitiveServerUrl = null;
|
||||
private Set<Integer> mRemoteSensitiveMessageTypes;
|
||||
@@ -101,6 +102,9 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
Utility.printExecption(LOG, e);
|
||||
}
|
||||
|
||||
try {
|
||||
mAllowSend2ForbiddenUser = Boolean.parseBoolean(mServer.getConfig().getProperty(BrokerConstants.MESSAGES_ALLOW_SEND_TO_FORBIDDEN_USER, "false"));
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
private void parseTypes(Collection<Integer> collection, String types) {
|
||||
@@ -132,6 +136,15 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
ErrorCode errorCode = ErrorCode.ERROR_CODE_SUCCESS;
|
||||
boolean isAdmin = requestSourceType == ProtoConstants.RequestSourceType.Request_From_Admin;
|
||||
if (message != null) {
|
||||
if(message.getContent().getContent().length() +
|
||||
message.getContent().getSearchableContent().length() +
|
||||
message.getContent().getData().size() +
|
||||
message.getContent().getExtra().length() +
|
||||
message.getContent().getPushContent().length() +
|
||||
message.getContent().getPushData().length() > 64 * 1024) {
|
||||
return ErrorCode.ERROR_CODE_MESSAGE_TOO_LARGE;
|
||||
}
|
||||
|
||||
boolean ignoreMsg = false;
|
||||
if (!isAdmin) { //admin do not check the right
|
||||
// 不能在端上直接发送撤回和群通知
|
||||
@@ -170,9 +183,11 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
}
|
||||
}
|
||||
|
||||
userStatus = m_messagesStore.getUserStatus(message.getConversation().getTarget());
|
||||
if (userStatus == ProtoConstants.UserStatus.Forbidden) {
|
||||
return ErrorCode.ERROR_CODE_USER_FORBIDDEN;
|
||||
if (!mAllowSend2ForbiddenUser) {
|
||||
userStatus = m_messagesStore.getUserStatus(message.getConversation().getTarget());
|
||||
if (userStatus == ProtoConstants.UserStatus.Forbidden) {
|
||||
return ErrorCode.ERROR_CODE_USER_FORBIDDEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,20 +232,13 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
}
|
||||
message = message.toBuilder().setFromUser(fromUser).setMessageId(messageId).setServerTimestamp(timestamp).build();
|
||||
|
||||
OutputClient outputClient = null;
|
||||
if(m_messagesStore.isForwardMessageWithClientInfo() && requestSourceType == ProtoConstants.RequestSourceType.Request_From_User && !StringUtil.isNullOrEmpty(clientID)) {
|
||||
MemorySessionStore.Session session = m_sessionsStore.getSession(clientID);
|
||||
if(session != null && session.getUsername().equals(fromUser)) {
|
||||
outputClient = new OutputClient(session.getPlatform(), clientID);
|
||||
}
|
||||
}
|
||||
|
||||
if (!StringUtil.isNullOrEmpty(mForwardUrl) && (mForwardMessageTypes.isEmpty() || mForwardMessageTypes.contains(message.getContent().getType())) && !(isAdmin && mNoForwardAdminMessage) && !mForwardExcludeMessageTypes.contains(message.getContent().getType())) {
|
||||
publisher.forwardMessage(message, mForwardUrl, outputClient);
|
||||
publisher.forwardMessage(message, mForwardUrl, clientID);
|
||||
}
|
||||
|
||||
if(!StringUtil.isNullOrEmpty(mMentionForwardUrl) && message.hasContent() && message.getContent().getMentionedType() != 0 && !(isAdmin && mNoForwardAdminMessage)) {
|
||||
publisher.forwardMessage(message, mMentionForwardUrl, outputClient);
|
||||
publisher.forwardMessage(message, mMentionForwardUrl, clientID);
|
||||
}
|
||||
|
||||
if (!isAdmin) {
|
||||
@@ -239,7 +247,7 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
if (matched != null && !matched.isEmpty()) {
|
||||
m_messagesStore.storeSensitiveMessage(message);
|
||||
if (!StringUtil.isNullOrEmpty(mSensitiveMessageForwardUrl)) {
|
||||
publisher.forwardMessage(message, mSensitiveMessageForwardUrl, outputClient);
|
||||
publisher.forwardMessage(message, mSensitiveMessageForwardUrl, clientID);
|
||||
}
|
||||
if (mSensitiveType == 0) {
|
||||
errorCode = ErrorCode.ERROR_CODE_SENSITIVE_MATCHED;
|
||||
@@ -256,7 +264,7 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
|
||||
} else {
|
||||
if(mRemoteSensitiveMessageTypes.contains(message.getContent().getType())) {
|
||||
final WFCMessage.Message finalMsg = message;
|
||||
publisher.forwardMessageWithCallback(message, mRemoteSensitiveServerUrl, new HttpUtils.HttpCallback() {
|
||||
publisher.forwardMessageWithCallback(message, clientID, mRemoteSensitiveServerUrl, new HttpUtils.HttpCallback() {
|
||||
@Override
|
||||
public void onSuccess(String content) {
|
||||
if(StringUtil.isNullOrEmpty(content)) {
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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 io.moquette.imhandler;
|
||||
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import io.moquette.spi.impl.Qos1PublishHandler;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import win.liyufan.im.IMTopic;
|
||||
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
|
||||
|
||||
@Handler(IMTopic.SetFriendExtraTopic)
|
||||
public class SetFriendExtraHandler extends IMHandler<WFCMessage.StringPair> {
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.StringPair request, Qos1PublishHandler.IMCallback callback) {
|
||||
long[] heads = new long[1];
|
||||
ErrorCode errorCode = m_messagesStore.setFriendExtraRequest(fromUser, request.getKey(), request.getValue(), heads);
|
||||
if (errorCode == ERROR_CODE_SUCCESS) {
|
||||
publisher.publishNotification(IMTopic.NotifyFriendTopic, fromUser, heads[0], clientID);
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
@@ -15,13 +15,18 @@ import io.netty.buffer.ByteBuf;
|
||||
import cn.wildfirechat.common.ErrorCode;
|
||||
import win.liyufan.im.IMTopic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Handler(IMTopic.UserSearchTopic)
|
||||
public class UserSearchHandler extends IMHandler<WFCMessage.SearchUserRequest> {
|
||||
@Override
|
||||
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.SearchUserRequest request, Qos1PublishHandler.IMCallback callback) {
|
||||
List<WFCMessage.User> users = m_messagesStore.searchUser(request.getKeyword(), request.getFuzzy(), request.getPage());
|
||||
List<WFCMessage.User> users = new ArrayList<>();
|
||||
ErrorCode errorCode = m_messagesStore.searchUser(fromUser, request.getKeyword(), request.getFuzzy(), request.getType(), request.getPage(), users);
|
||||
if(errorCode != ErrorCode.ERROR_CODE_SUCCESS) {
|
||||
return errorCode;
|
||||
}
|
||||
WFCMessage.SearchUserResult.Builder builder = WFCMessage.SearchUserResult.newBuilder();
|
||||
builder.addAllEntry(users);
|
||||
byte[] data = builder.build().toByteArray();
|
||||
|
||||
@@ -36,6 +36,8 @@ import java.util.function.Function;
|
||||
|
||||
import static cn.wildfirechat.common.IMExceptionEvent.EventType.RDBS_Exception;
|
||||
import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent;
|
||||
import static cn.wildfirechat.proto.ProtoConstants.UserSearchUserType.UserSearchUserType_ONLY_ROBOT;
|
||||
import static cn.wildfirechat.proto.ProtoConstants.UserSearchUserType.UserSearchUserType_ONLY_USER;
|
||||
import static io.moquette.BrokerConstants.GROUP_INFO_MARK_DELETION;
|
||||
import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE;
|
||||
import static cn.wildfirechat.proto.ProtoConstants.SearchUserType.*;
|
||||
@@ -169,7 +171,7 @@ public class DatabaseStore {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<WFCMessage.User> searchUserByNameMobileUserId(String keyword, int searchType) {
|
||||
List<WFCMessage.User> searchUserByNameMobileUserId(String keyword, int searchType, int userType) {
|
||||
ArrayList<WFCMessage.User> out = new ArrayList<>();
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
@@ -203,7 +205,15 @@ public class DatabaseStore {
|
||||
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
|
||||
if(userType == UserSearchUserType_ONLY_USER) {
|
||||
sql += " and _type <> 2 "; //can not search device
|
||||
sql += " and _type <> 1 ";
|
||||
} else if(userType == UserSearchUserType_ONLY_ROBOT) {
|
||||
sql += " and _type = 1 ";
|
||||
} else {
|
||||
sql += " and _type <> 2 "; //can not search device
|
||||
}
|
||||
sql += " and _deleted = 0 ";
|
||||
|
||||
if(searchType == SearchUserType_Name || searchType == SearchUserType_Mobile || searchType == SearchUserType_UserId) {
|
||||
sql += " limit 1";
|
||||
@@ -408,7 +418,7 @@ public class DatabaseStore {
|
||||
return out;
|
||||
}
|
||||
|
||||
List<WFCMessage.User> searchUserByDisplayName(String keyword, int page, List<WFCMessage.User> nameOrIdMatched) {
|
||||
List<WFCMessage.User> searchUserByDisplayName(String keyword, int userType, int page, List<WFCMessage.User> nameOrIdMatched) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
@@ -419,7 +429,18 @@ public class DatabaseStore {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select u._uid, u._name, u._display_name, u._portrait, u._mobile, u._gender, u._email, u._address, u._company, u._social, u._extra, u._dt, u._type " +
|
||||
" from t_user u left join (select _uid, _value from t_user_setting where _scope = 27) s on u._uid = s._uid " +
|
||||
" where u._display_name like ? ESCAPE '!' and u._type <> 2 and u._deleted = 0 ";
|
||||
" where u._display_name like ? ESCAPE '!' ";
|
||||
|
||||
if(userType == UserSearchUserType_ONLY_USER) {
|
||||
sql += " and u._type <> 2 ";
|
||||
sql += " and u._type <> 1 ";
|
||||
} else if(userType == UserSearchUserType_ONLY_ROBOT) {
|
||||
sql += " and u._type = 1 ";
|
||||
} else {
|
||||
sql += " and u._type <> 2 ";
|
||||
}
|
||||
sql += " and u._deleted = 0 ";
|
||||
|
||||
if(nameOrIdMatched.size() == 1) {
|
||||
sql += " and u._uid <> ? and u._name <> ?";
|
||||
} else if(nameOrIdMatched.size() == 2) {
|
||||
@@ -523,15 +544,15 @@ public class DatabaseStore {
|
||||
return out;
|
||||
}
|
||||
|
||||
List<WFCMessage.User> searchUserFromDB(String keyword, int searchType, int page) {
|
||||
List<WFCMessage.User> nameOrIdMatched = searchUserByNameMobileUserId(keyword, searchType);
|
||||
List<WFCMessage.User> searchUserFromDB(String keyword, int searchType, int userType, int page) {
|
||||
List<WFCMessage.User> nameOrIdMatched = searchUserByNameMobileUserId(keyword, searchType, userType);
|
||||
List<WFCMessage.User> out = new ArrayList<>();
|
||||
if(page == 0) {
|
||||
out.addAll(nameOrIdMatched);
|
||||
}
|
||||
|
||||
if(searchType == SearchUserType_General || searchType == SearchUserType_Name_Mobile_DisplayName) {
|
||||
List<WFCMessage.User> general = searchUserByDisplayName(keyword, page, nameOrIdMatched);
|
||||
List<WFCMessage.User> general = searchUserByDisplayName(keyword, userType, page, nameOrIdMatched);
|
||||
general.removeAll(nameOrIdMatched);
|
||||
out.addAll(general);
|
||||
}
|
||||
@@ -1811,6 +1832,31 @@ public class DatabaseStore {
|
||||
});
|
||||
}
|
||||
|
||||
void updateSessionIp(String uid, String cid, String ip) {
|
||||
mScheduler.execute(()->{
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "update t_user_session set _ip = ? where `_uid` = ? and `_cid` = ?";
|
||||
statement = connection.prepareStatement(sql);
|
||||
int index = 1;
|
||||
statement.setString(index++, ip);
|
||||
statement.setString(index++, uid);
|
||||
statement.setString(index++, cid);
|
||||
|
||||
int c = statement.executeUpdate();
|
||||
LOG.info("Update rows {}", c);
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void clearMultiEndpoint(String uid, String clientId, int platform) {
|
||||
LOG.info("clearMultiEndpoint {}, {}", uid, clientId);
|
||||
Connection connection = null;
|
||||
@@ -1824,6 +1870,10 @@ public class DatabaseStore {
|
||||
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";
|
||||
} else if(platform == ProtoConstants.Platform.Platform_AndroidWearable || platform == ProtoConstants.Platform.Platform_HarmonyWearable) {
|
||||
sql = "update t_user_session set `_deleted` = ?, `_token` = ?, `_voip_token` = ?, `_dt` = ? where `_uid`=? and (`_platform` = ? or `_platform` = ?) and `_cid` <> ? and `_deleted` = 0";
|
||||
} else if(platform == ProtoConstants.Platform.Platform_AndroidTV || platform == ProtoConstants.Platform.Platform_AppleTV || platform == ProtoConstants.Platform.Platform_HarmonyTV) {
|
||||
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 {
|
||||
sql = "update t_user_session set `_deleted` = ?, `_token` = ?, `_voip_token` = ?, `_dt` = ? where `_uid`=? and `_platform` = ? and `_cid` <> ? and `_deleted` = 0";
|
||||
}
|
||||
@@ -1851,6 +1901,13 @@ public class DatabaseStore {
|
||||
statement.setInt(index++, ProtoConstants.Platform.Platform_iPad);
|
||||
statement.setInt(index++, ProtoConstants.Platform.Platform_APad);
|
||||
statement.setInt(index++, ProtoConstants.Platform.Platform_HarmonyPad);
|
||||
} else if(platform == ProtoConstants.Platform.Platform_AndroidWearable || platform == ProtoConstants.Platform.Platform_HarmonyWearable) {
|
||||
statement.setInt(index++, ProtoConstants.Platform.Platform_AndroidWearable);
|
||||
statement.setInt(index++, ProtoConstants.Platform.Platform_HarmonyWearable);
|
||||
} else if(platform == ProtoConstants.Platform.Platform_AndroidTV || platform == ProtoConstants.Platform.Platform_AppleTV || platform == ProtoConstants.Platform.Platform_HarmonyTV) {
|
||||
statement.setInt(index++, ProtoConstants.Platform.Platform_AndroidTV);
|
||||
statement.setInt(index++, ProtoConstants.Platform.Platform_AppleTV);
|
||||
statement.setInt(index++, ProtoConstants.Platform.Platform_HarmonyTV);
|
||||
} else {
|
||||
statement.setInt(index++, platform);
|
||||
}
|
||||
@@ -3034,6 +3091,102 @@ public class DatabaseStore {
|
||||
return outList;
|
||||
}
|
||||
|
||||
List<WFCMessage.User> getUserInfosByMobile(String mobile, boolean includeDeleted) {
|
||||
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 `_mobile` = ?";
|
||||
if(!includeDeleted) {
|
||||
sql += " and `_deleted` = 0";
|
||||
}
|
||||
statement = connection.prepareStatement(sql);
|
||||
statement.setString(1, mobile);
|
||||
|
||||
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) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
@@ -3131,6 +3284,97 @@ public class DatabaseStore {
|
||||
return outList;
|
||||
}
|
||||
|
||||
List<WFCMessage.Robot> getAllRobots(int count, int offset) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
List<WFCMessage.Robot> outList = new ArrayList<>();
|
||||
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select `_uid`, `_owner`" +
|
||||
", `_secret`" +
|
||||
", `_callback`" +
|
||||
", `_state`" +
|
||||
", `_extra`" +
|
||||
", `_dt` from t_robot limit ? offset ?";
|
||||
statement = connection.prepareStatement(sql);
|
||||
|
||||
int index = 1;
|
||||
statement.setInt(1, count);
|
||||
statement.setInt(2, offset);
|
||||
|
||||
rs = statement.executeQuery();
|
||||
while (rs.next()) {
|
||||
WFCMessage.Robot.Builder builder = WFCMessage.Robot.newBuilder();
|
||||
index = 1;
|
||||
String value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setUid(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setOwner(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setSecret(value);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setCallback(value);
|
||||
|
||||
|
||||
int state = rs.getInt(index++);
|
||||
builder.setState(state);
|
||||
|
||||
value = rs.getString(index++);
|
||||
value = (value == null ? "" : value);
|
||||
builder.setExtra(value);
|
||||
|
||||
long longValue = rs.getLong(index++);
|
||||
|
||||
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<String> getUserRobotIds(String userId) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
List<String> outList = new ArrayList<>();
|
||||
try {
|
||||
connection = DBUtil.getConnection();
|
||||
String sql = "select _uid from t_robot where _owner = ? and _state = 0";
|
||||
statement = connection.prepareStatement(sql);
|
||||
|
||||
int index = 1;
|
||||
statement.setString(1, userId);
|
||||
|
||||
rs = statement.executeQuery();
|
||||
while (rs.next()) {
|
||||
outList.add(rs.getString(1));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, RDBS_Exception);
|
||||
} finally {
|
||||
DBUtil.closeDB(connection, statement, rs);
|
||||
}
|
||||
return outList;
|
||||
}
|
||||
|
||||
|
||||
Set<String> getAllEnds(boolean fromUserTable) {
|
||||
Connection connection = null;
|
||||
PreparedStatement statement = null;
|
||||
|
||||
@@ -56,7 +56,10 @@ import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static cn.wildfirechat.common.IMExceptionEvent.EventType.EVENT_CALLBACK_Exception;
|
||||
import static cn.wildfirechat.proto.ProtoConstants.ChannelState.*;
|
||||
@@ -75,8 +78,7 @@ import static io.moquette.BrokerConstants.*;
|
||||
import static io.moquette.server.Constants.MAX_CHATROOM_MESSAGE_QUEUE;
|
||||
import static io.moquette.server.Constants.MAX_MESSAGE_QUEUE;
|
||||
import static cn.wildfirechat.pojos.MyInfoType.*;
|
||||
import static win.liyufan.im.UserSettingScope.kUserSettingAddFriendStrategy;
|
||||
import static win.liyufan.im.UserSettingScope.kUserSettingPCOnline;
|
||||
import static win.liyufan.im.UserSettingScope.*;
|
||||
|
||||
public class MemoryMessagesStore implements IMessagesStore {
|
||||
private static final String MESSAGES_MAP = "messages_map";
|
||||
@@ -156,6 +158,8 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
private long mFriendRejectDuration = 30 * 24 * 60 * 60 * 1000;
|
||||
private long mFriendRequestExpiration = 7 * 24 * 60 * 60 * 1000;
|
||||
private RateLimiter mFriendRateLimiter;
|
||||
private RateLimiter mFriendSearchEmpthMobileRateLimiter;
|
||||
private RateLimiter mFriendSearchRateLimiter;
|
||||
private boolean mFriendRobotAutoAccept = true;
|
||||
|
||||
private long mPushExpiredTimes = 604800000L;
|
||||
@@ -167,9 +171,10 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
private Set<String> mAllowStrangerChatSet = new HashSet<>();
|
||||
private Set<Integer> mAllowStrangerLineSet = new HashSet<>();
|
||||
private boolean mDisableStrangerAddGroup = false;
|
||||
private boolean mGroupAllowPartSuccess = false;
|
||||
|
||||
private boolean mIDUseUUID = true;
|
||||
|
||||
private boolean mSensitiveOnlyMessage = true;
|
||||
private Set<String> mClientSignatureSet = new HashSet<>();
|
||||
private boolean mRejectEmptySignature = true;
|
||||
|
||||
@@ -200,13 +205,27 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
private int mGroupForbiddenClientOperation;
|
||||
private int mSyncDataPartSize = 0;
|
||||
private boolean keepDisplayNameWhenDestroyUser = true;
|
||||
private boolean keepFullInfoWhenDestroyUser = false;
|
||||
private boolean keepMobileWhenDestroyUser = false;
|
||||
private boolean keepMessagesWhenDestroyUser = false;
|
||||
|
||||
private String mRecallForwardUrl = null;
|
||||
|
||||
private boolean mBroadcastTargetFromUserTable = false;
|
||||
|
||||
private boolean mForwardMessageWithClientInfo = false;
|
||||
private boolean mForwardMessageWithSenderInfo = false;
|
||||
private boolean mForwardMessageWithTargetInfo = false;
|
||||
|
||||
private boolean mRobotCallbackWithClientInfo = false;
|
||||
private boolean mRobotCallbackWithSenderInfo = false;
|
||||
private boolean mRobotCallbackWithTargetInfo = false;
|
||||
private boolean mRobotMentionExternalRobot = false;
|
||||
private int mRobotGetUserInfoMask = 0;
|
||||
|
||||
private boolean mChannelCallbackWithClientInfo = false;
|
||||
private boolean mChannelCallbackWithSenderInfo = false;
|
||||
private boolean mChannelCallbackWithTargetInfo = false;
|
||||
private boolean mChannelNewCallbackFeature = true;
|
||||
|
||||
private Set<Integer> mUserHideProperties = new HashSet<>();
|
||||
@@ -321,7 +340,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
printMissConfigLog(FRIEND_Disable_NickName_Search, mDisableNicknameSearch + "");
|
||||
}
|
||||
try {
|
||||
mDisableUserIdSearch = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.FRIEND_Disable_UserId_Search, "true"));
|
||||
mDisableUserIdSearch = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.FRIEND_Disable_UserId_Search, "false"));
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
@@ -365,6 +384,21 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
try {
|
||||
int rateLimit = Integer.parseInt(m_Server.getConfig().getProperty(FRIEND_Search_Mobile_Empty_Rate_Limit, "0"));
|
||||
if(rateLimit > 0) {
|
||||
mFriendSearchEmpthMobileRateLimiter = new RateLimiter(86400, rateLimit);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
try {
|
||||
int rateLimit = Integer.parseInt(m_Server.getConfig().getProperty(FRIEND_Search_Rate_Limit, "0"));
|
||||
if(rateLimit > 0) {
|
||||
mFriendSearchRateLimiter = new RateLimiter(86400, rateLimit);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
try {
|
||||
mFriendRobotAutoAccept = Boolean.parseBoolean(m_Server.getConfig().getProperty(BrokerConstants.FRIEND_Request_Robot_Auto_Accept, "true"));
|
||||
@@ -589,6 +623,17 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
try {
|
||||
keepFullInfoWhenDestroyUser = "true".equals(server.getConfig().getProperty(USER_KEEP_FULL_INFO_WHEN_DESTROY));
|
||||
} catch (Exception e) {}
|
||||
|
||||
try {
|
||||
keepMobileWhenDestroyUser = "true".equals(server.getConfig().getProperty(USER_KEEP_MOBILE_WHEN_DESTROY));
|
||||
} catch (Exception e) {}
|
||||
|
||||
try {
|
||||
keepMessagesWhenDestroyUser = "true".equals(server.getConfig().getProperty(USER_KEEP_MESSAGES_WHEN_DESTROY));
|
||||
} catch (Exception e) {}
|
||||
|
||||
|
||||
try {
|
||||
@@ -608,9 +653,13 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
|
||||
try {
|
||||
mForwardMessageWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.MESSAGE_Forward_With_Client_Info, "false"));
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
mForwardMessageWithSenderInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.MESSAGE_Forward_With_Sender_Info, "false"));
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
mForwardMessageWithTargetInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.MESSAGE_Forward_With_Target_Info, "false"));
|
||||
} catch (Exception e) {}
|
||||
|
||||
try {
|
||||
mBroadcastTargetFromUserTable = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.BROADCAST_Target_From_User_Table, "false"));
|
||||
@@ -619,18 +668,39 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
|
||||
try {
|
||||
mRobotCallbackWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.ROBOT_Callback_With_Client_Info, "false"));
|
||||
mGroupAllowPartSuccess = "true".equals(server.getConfig().getProperty(BrokerConstants.GROUP_ADD_MEMBER_ALLOW_PART_SUCCESS, "false"));
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
mRobotCallbackWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.ROBOT_Callback_With_Client_Info, "false"));
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
mRobotCallbackWithSenderInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.ROBOT_Callback_With_Sender_Info, "false"));
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
mRobotCallbackWithTargetInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.ROBOT_Callback_With_Target_Info, "false"));
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
mRobotMentionExternalRobot = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.ROBOT_Mention_External_Robot, "false"));
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
mRobotGetUserInfoMask = Integer.parseInt(server.getConfig().getProperty(BrokerConstants.ROBOT_Get_User_Info_Mask, "0"));
|
||||
} catch (Exception e) {}
|
||||
|
||||
try {
|
||||
mChannelCallbackWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_Callback_With_Client_Info, "false"));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
mChannelCallbackWithSenderInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_Callback_With_Sender_Info, "false"));
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
mChannelCallbackWithTargetInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_Callback_With_Target_Info, "false"));
|
||||
} catch (Exception e) {}
|
||||
|
||||
try {
|
||||
mChannelNewCallbackFeature = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_New_Callback_Feature, "true"));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
|
||||
try {
|
||||
mRecallForwardUrl = server.getConfig().getProperty(BrokerConstants.MESSAGE_RecallMsg_Forward_Url);
|
||||
@@ -642,6 +712,11 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
mIDUseUUID = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.ID_USE_UUID, "false"));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
try {
|
||||
mSensitiveOnlyMessage = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SENSITIVE_Only_Message, "true"));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
private void printMissConfigLog(String config, String defaultValue) {
|
||||
@@ -708,13 +783,34 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
int pullType = ProtoConstants.PullType.Pull_Normal;
|
||||
|
||||
if (type == ProtoConstants.ConversationType.ConversationType_Private) {
|
||||
notifyReceivers.add(fromUser);
|
||||
if(message.getToCount() > 0) {
|
||||
if(message.getToList().contains(message.getConversation().getTarget())) {
|
||||
notifyReceivers.add(message.getConversation().getTarget());
|
||||
if(mRobotMentionExternalRobot && message.getConversation().getTarget().contains("|")) {
|
||||
String[] ss = message.getConversation().getTarget().split("\\|");
|
||||
notifyReceivers.add(ss[0]);
|
||||
notifyReceivers.add(ss[1]);
|
||||
if(!message.getToList().isEmpty()) {
|
||||
notifyReceivers.addAll(message.getToList());
|
||||
} else if(!StringUtil.isNullOrEmpty(message.getToUser())) {
|
||||
notifyReceivers.add(message.getToUser());
|
||||
}
|
||||
} else {
|
||||
notifyReceivers.add(message.getConversation().getTarget());
|
||||
notifyReceivers.add(fromUser);
|
||||
if (message.getToCount() > 0) {
|
||||
if (message.getToList().contains(message.getConversation().getTarget())) {
|
||||
notifyReceivers.add(message.getConversation().getTarget());
|
||||
}
|
||||
} else {
|
||||
notifyReceivers.add(message.getConversation().getTarget());
|
||||
}
|
||||
}
|
||||
if (mRobotMentionExternalRobot && message.getContent().getMentionedTargetCount() > 0) {
|
||||
for (String mentioned : message.getContent().getMentionedTargetList()) {
|
||||
if (!notifyReceivers.contains(mentioned)) {
|
||||
WFCMessage.User user = getUserInfo(mentioned);
|
||||
if(user != null && user.getType() == ProtoConstants.UserType.UserType_Robot) {
|
||||
notifyReceivers.add(mentioned);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pullType = ProtoConstants.PullType.Pull_Normal;
|
||||
} else if (type == ProtoConstants.ConversationType.ConversationType_Group) {
|
||||
@@ -744,6 +840,16 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mRobotMentionExternalRobot && message.getContent().getMentionedTargetCount() > 0) {
|
||||
for (String mentioned : message.getContent().getMentionedTargetList()) {
|
||||
if (!notifyReceivers.contains(mentioned)) {
|
||||
WFCMessage.User user = getUserInfo(mentioned);
|
||||
if(user != null && user.getType() == ProtoConstants.UserType.UserType_Robot) {
|
||||
notifyReceivers.add(mentioned);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pullType = ProtoConstants.PullType.Pull_Normal;
|
||||
} else if (type == ProtoConstants.ConversationType.ConversationType_ChatRoom) {
|
||||
boolean isDirect = !StringUtil.isNullOrEmpty(message.getToUser()) || !message.getToList().isEmpty();
|
||||
@@ -816,6 +922,18 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return pullType;
|
||||
}
|
||||
|
||||
private final Map<String, Integer> unreceivedMsgCount = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void increaseUnreceivedMsgCount(String user) {
|
||||
unreceivedMsgCount.compute(user, (s, integer) -> integer == null ? 1 : integer+1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUnreceivedMsgCount(String user) {
|
||||
return unreceivedMsgCount.getOrDefault(user, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAllEnds() {
|
||||
return databaseStore.getAllEnds(mBroadcastTargetFromUserTable);
|
||||
@@ -830,7 +948,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
MemorySessionStore.Session session = m_Server.getStore().sessionsStore().getSession(exceptClientId);
|
||||
session.refreshLastActiveTime();
|
||||
if (pullType != ProtoConstants.PullType.Pull_ChatRoom) {
|
||||
session.setUnReceivedMsgs(0);
|
||||
unreceivedMsgCount.put(user, 0);
|
||||
} else {
|
||||
session.refreshLastChatroomActiveTime();
|
||||
}
|
||||
@@ -900,11 +1018,13 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
session.setPullHistoryMsg(true);
|
||||
}
|
||||
|
||||
long previousCurrent;
|
||||
while (true) {
|
||||
Map.Entry<Long, Long> entry = maps.higherEntry(current);
|
||||
if (entry == null) {
|
||||
break;
|
||||
}
|
||||
previousCurrent = current;
|
||||
current = entry.getKey();
|
||||
long targetMessageId = entry.getValue();
|
||||
|
||||
@@ -933,6 +1053,8 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
if (size >= 512 * 1024) { //3M
|
||||
if(builder.getMessageCount() == 0){
|
||||
builder.addMessage(bundle.getMessage());
|
||||
} else {
|
||||
current = previousCurrent;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1256,7 +1378,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode canAddGroupMembers(String fromUser, List<WFCMessage.GroupMember> memberList) {
|
||||
public ErrorCode canAddGroupMembers(String fromUser, List<WFCMessage.GroupMember> memberList, Map<String, Integer> failedMembers) {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
MultiMap<String, FriendData> friendsMap = hzInstance.getMultiMap(USER_FRIENDS);
|
||||
IMap<String, WFCMessage.User> mUserMap = hzInstance.getMap(USERS);
|
||||
@@ -1282,7 +1404,12 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
for (FriendData friendData : friendDatas) {
|
||||
if (friendData.getFriendUid().equals(fromUser)) {
|
||||
if (friendData.getBlacked() == 1) {
|
||||
return ErrorCode.ERROR_CODE_IN_BLACK_LIST;
|
||||
LOG.error("Add group member failure, because inviter {} is blocked by invitee {}", fromUser, targetUser);
|
||||
if(isGroupAllowPartSuccess()) {
|
||||
failedMembers.put(targetUser, 1); //black
|
||||
} else {
|
||||
return ErrorCode.ERROR_CODE_IN_BLACK_LIST;
|
||||
}
|
||||
} else {
|
||||
if (friendData.getState() == 0) {
|
||||
allow = true;
|
||||
@@ -1306,7 +1433,11 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
continue;
|
||||
}
|
||||
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
if(isGroupAllowPartSuccess()) {
|
||||
failedMembers.put(targetUser, 2);//stranger
|
||||
} else {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (WFCMessage.GroupMember groupMember : memberList) {
|
||||
@@ -1323,7 +1454,12 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
for (FriendData friendData : friendDatas) {
|
||||
if (friendData.getFriendUid().equals(fromUser)) {
|
||||
if (friendData.getBlacked() == 1) {
|
||||
return ErrorCode.ERROR_CODE_IN_BLACK_LIST;
|
||||
LOG.error("Add group member failure, because inviter {} is blocked by invitee {}", fromUser, targetUser);
|
||||
if(isGroupAllowPartSuccess()) {
|
||||
failedMembers.put(targetUser, 1); //black
|
||||
} else {
|
||||
return ErrorCode.ERROR_CODE_IN_BLACK_LIST;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@@ -1335,7 +1471,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
|
||||
@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, Map<String, Integer> failedMembers) {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
IMap<String, WFCMessage.GroupInfo> mIMap = hzInstance.getMap(GROUPS_MAP);
|
||||
|
||||
@@ -1357,6 +1493,9 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
List<WFCMessage.GroupMember> updatedMemberList = new ArrayList<>();
|
||||
boolean hasOwnerMember = false;
|
||||
for (WFCMessage.GroupMember member : memberList) {
|
||||
if(failedMembers.containsKey(member.getMemberId())) {
|
||||
continue;
|
||||
}
|
||||
WFCMessage.GroupMember.Builder builder = member.toBuilder();
|
||||
builder.setUpdateDt(dt).setCreateDt(dt);
|
||||
if (member.getMemberId().equals(owner)) {
|
||||
@@ -1551,7 +1690,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode addGroupMembers(String operator, boolean isAdmin, String groupId, List<WFCMessage.GroupMember> memberList, String extra) {
|
||||
public ErrorCode addGroupMembers(String operator, boolean isAdmin, String groupId, List<WFCMessage.GroupMember> memberList, String extra, Map<String, Integer> failedMembers) {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
IMap<String, WFCMessage.GroupInfo> mIMap = hzInstance.getMap(GROUPS_MAP);
|
||||
|
||||
@@ -1624,6 +1763,10 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
List<WFCMessage.GroupMember> tmp = new ArrayList<>();
|
||||
int newMemberCount = 0;
|
||||
for (WFCMessage.GroupMember member : memberList) {
|
||||
if(failedMembers.containsKey(member.getMemberId())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (existMemberIds.contains(member.getMemberId()) && member.getType() != GroupMemberType_Removed) {
|
||||
if(!isAdmin)
|
||||
continue;
|
||||
@@ -1656,7 +1799,11 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
|
||||
if (memberList.size() == 0) {
|
||||
if (!isAdmin) {
|
||||
return ErrorCode.ERROR_CODE_ALREADY_IN_GROUP;
|
||||
if(failedMembers.isEmpty()) {
|
||||
return ErrorCode.ERROR_CODE_ALREADY_IN_GROUP;
|
||||
} else {
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
@@ -1675,6 +1822,10 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
|
||||
List<String> memberIds = new ArrayList<>();
|
||||
for (WFCMessage.GroupMember member : memberList) {
|
||||
if(failedMembers.containsKey(member.getMemberId())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (member.getType() != GroupMemberType_Removed) {
|
||||
memberIds.add(member.getMemberId());
|
||||
}
|
||||
@@ -1900,6 +2051,19 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
if (!isAllow) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
if (modifyType == Modify_Group_Name && !StringUtil.isNullOrEmpty(value)) {
|
||||
if(!mSensitiveOnlyMessage) {
|
||||
Set<String> matched = handleSensitiveWord(value);
|
||||
if (matched != null && !matched.isEmpty()) {
|
||||
return ErrorCode.ERROR_CODE_SENSITIVE_MATCHED;
|
||||
}
|
||||
}
|
||||
|
||||
if(!isAllowName(value)) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (oldInfo.getType() == ProtoConstants.GroupType.GroupType_Normal) {
|
||||
@@ -1937,6 +2101,14 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
newInfoBuilder.setPrivateChat(Integer.parseInt(value));
|
||||
else if(modifyType == Modify_Group_Searchable)
|
||||
newInfoBuilder.setSearchable(Integer.parseInt(value));
|
||||
else if(modifyType == Modify_Group_Type) {
|
||||
int newType = Integer.parseInt(value);
|
||||
if(newType < 0 || newType > ProtoConstants.GroupType.GroupType_Organization) {
|
||||
LOG.error("modify group type failure, invalid group type {}", newType);
|
||||
return ErrorCode.INVALID_PARAMETER;
|
||||
}
|
||||
newInfoBuilder.setType(newType);
|
||||
}
|
||||
else
|
||||
return ErrorCode.INVALID_PARAMETER;
|
||||
|
||||
@@ -2265,6 +2437,10 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
|
||||
if(newOwner.equals(groupInfo.getOwner())) {
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
//check the new owner is in member list? is that necessary?
|
||||
MultiMap<String, WFCMessage.GroupMember> groupMembers = hzInstance.getMultiMap(GROUP_MEMBERS);
|
||||
Collection<WFCMessage.GroupMember> members = groupMembers.get(groupId);
|
||||
@@ -2454,7 +2630,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
boolean isExpired = false;
|
||||
if (!canRecall && message.getFromUser().equals(operatorId)) {
|
||||
if (now - message.getServerTimestamp() > mRecallTimeLimit * 1000) {
|
||||
if (mRecallTimeLimit >= 0 && now - message.getServerTimestamp() > mRecallTimeLimit * 1000) {
|
||||
isExpired = true;
|
||||
} else {
|
||||
canRecall = true;
|
||||
@@ -2623,8 +2799,9 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
} finally {
|
||||
mWriteLock.unlock();
|
||||
}
|
||||
|
||||
databaseStore.clearUserMessage(userId);
|
||||
if(!keepMessagesWhenDestroyUser) {
|
||||
databaseStore.clearUserMessage(userId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2728,6 +2905,19 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
) {
|
||||
switch (entry.getType()) {
|
||||
case Modify_DisplayName:
|
||||
if(!StringUtil.isNullOrEmpty(entry.getValue())) {
|
||||
if (!mSensitiveOnlyMessage) {
|
||||
Set<String> matched = handleSensitiveWord(entry.getValue());
|
||||
if (matched != null && !matched.isEmpty()) {
|
||||
return ErrorCode.ERROR_CODE_SENSITIVE_MATCHED;
|
||||
}
|
||||
}
|
||||
|
||||
if(!isAllowName(entry.getValue())) {
|
||||
return ErrorCode.ERROR_CODE_NOT_RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
builder.setDisplayName(entry.getValue());
|
||||
modified = true;
|
||||
break;
|
||||
@@ -2840,6 +3030,8 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
|
||||
String pcValue = null;
|
||||
String padValue = null;
|
||||
String wearableValue = null;
|
||||
String tvValue = null;
|
||||
for (MemorySessionStore.Session s : m_Server.getStore().sessionsStore().sessionForUser(session.username)) {
|
||||
if (s.getDeleted() != 0 || !m_Server.getConnectionsManager().isConnected(s.getClientID())) {
|
||||
continue;
|
||||
@@ -2857,6 +3049,15 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
case Platform_HarmonyPad:
|
||||
padValue = System.currentTimeMillis() + "|" + s.getPlatform() + "|" + s.getClientID() + "|" + s.getPhoneName();
|
||||
break;
|
||||
case Platform_AndroidWearable:
|
||||
case Platform_HarmonyWearable:
|
||||
wearableValue = System.currentTimeMillis() + "|" + s.getPlatform() + "|" + s.getClientID() + "|" + s.getPhoneName();
|
||||
break;
|
||||
case Platform_AndroidTV:
|
||||
case Platform_AppleTV:
|
||||
case Platform_HarmonyTV:
|
||||
tvValue = System.currentTimeMillis() + "|" + s.getPlatform() + "|" + s.getClientID() + "|" + s.getPhoneName();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2871,6 +3072,16 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
if (!isOnlineValueEqual(padentry, padValue)) {
|
||||
updateUserSettings(session.username, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("Pad").setValue(padValue==null?"":padValue).build(), session.clientID);
|
||||
}
|
||||
|
||||
WFCMessage.UserSettingEntry wearableEntry = getUserSetting(session.getUsername(), kUserSettingPCOnline, "Wearable");
|
||||
if (!isOnlineValueEqual(wearableEntry, wearableValue)) {
|
||||
updateUserSettings(session.username, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("Wearable").setValue(wearableValue==null?"":wearableValue).build(), session.clientID);
|
||||
}
|
||||
|
||||
WFCMessage.UserSettingEntry tvEntry = getUserSetting(session.getUsername(), kUserSettingPCOnline, "TV");
|
||||
if (!isOnlineValueEqual(tvEntry, tvValue)) {
|
||||
updateUserSettings(session.username, WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingPCOnline).setKey("TV").setValue(tvValue==null?"":tvValue).build(), session.clientID);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2989,37 +3200,29 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
IMap<String, WFCMessage.User> mUserMap = hzInstance.getMap(USERS);
|
||||
WFCMessage.User us = mUserMap.get(userId);
|
||||
if (us != null) {
|
||||
if (keepDisplayNameWhenDestroyUser) {
|
||||
us = WFCMessage.User.newBuilder()
|
||||
.setUid(userId)
|
||||
.setUpdateDt(System.currentTimeMillis())
|
||||
.setName(userId)
|
||||
.setDeleted(1)
|
||||
.clearAddress()
|
||||
.clearCompany()
|
||||
.clearEmail()
|
||||
.clearExtra()
|
||||
.clearMobile()
|
||||
.clearPortrait()
|
||||
.clearSocial()
|
||||
.build();
|
||||
WFCMessage.User.Builder builder = us.toBuilder().setUpdateDt(System.currentTimeMillis()).setDeleted(1);
|
||||
|
||||
if(keepFullInfoWhenDestroyUser) {
|
||||
if(!keepMobileWhenDestroyUser) {
|
||||
builder.clearMobile();
|
||||
}
|
||||
} else {
|
||||
us = WFCMessage.User.newBuilder()
|
||||
.setUid(userId)
|
||||
.setUpdateDt(System.currentTimeMillis())
|
||||
builder.setUid(userId)
|
||||
.setName(userId)
|
||||
.setDeleted(1)
|
||||
.clearDisplayName()
|
||||
.clearAddress()
|
||||
.clearCompany()
|
||||
.clearEmail()
|
||||
.clearExtra()
|
||||
.clearMobile()
|
||||
.clearPortrait()
|
||||
.clearSocial()
|
||||
.build();
|
||||
.clearGender()
|
||||
.clearSocial();
|
||||
if (!keepDisplayNameWhenDestroyUser) {
|
||||
builder.clearDisplayName();
|
||||
}
|
||||
}
|
||||
|
||||
us = builder.build();
|
||||
try {
|
||||
databaseStore.updateUser(us);
|
||||
} catch (Exception e) {
|
||||
@@ -3028,8 +3231,8 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
mUserMap.put(userId, us);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUserInfo(WFCMessage.User user) throws Exception {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
@@ -3069,15 +3272,62 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return databaseStore.getUserInfosByEmail(email);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WFCMessage.User> getUserInfosByMobile(String mobile, boolean includeDeleted) {
|
||||
return databaseStore.getUserInfosByMobile(mobile, includeDeleted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WFCMessage.User> getUserInfoList(int count, int offset) {
|
||||
return databaseStore.getAllUsers(count, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WFCMessage.User> searchUser(String keyword, int searchType, int page) {
|
||||
public List<WFCMessage.Robot> getRobotInfoList(int count, int offset) {
|
||||
return databaseStore.getAllRobots(count, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUserRobotIds(String userId) {
|
||||
return databaseStore.getUserRobotIds(userId);
|
||||
}
|
||||
|
||||
// 电话号码校验正则表达式(支持中国大陆手机号和固话)
|
||||
private static final String PHONE_REGEX = "^\\s*" + // 允许开头空白
|
||||
"(?:" +
|
||||
"(1[0-9])\\d{9}" +
|
||||
"|" +
|
||||
"((0\\d{2,3})|(\\(0\\d{2,3}\\)))" +
|
||||
"[-\\s.]?" +
|
||||
"\\d{7,8}" +
|
||||
"|" +
|
||||
"\\d{7,8}" +
|
||||
")\\s*$";
|
||||
|
||||
private static final Pattern PHONE_PATTERN = Pattern.compile(PHONE_REGEX);
|
||||
private static final Pattern PHONE_PART_PATTERN = Pattern.compile("^1\\d{0,10}$");
|
||||
|
||||
public static boolean isPhoneNumber(String phone) {
|
||||
if (phone == null || phone.trim().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
Matcher matcher = PHONE_PATTERN.matcher(phone);
|
||||
return matcher.matches();
|
||||
}
|
||||
|
||||
public static boolean isPhoneNumberPart(String str) {
|
||||
if (str == null || str.trim().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Matcher matcher = PHONE_PART_PATTERN.matcher(str);
|
||||
return matcher.matches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode searchUser(String userId, String keyword, int searchType, int userType, int page, List<WFCMessage.User> users) {
|
||||
if (mDisableSearch) {
|
||||
return new ArrayList<>();
|
||||
return ErrorCode.ERROR_CODE_NOT_IMPLEMENT;
|
||||
}
|
||||
|
||||
if (mDisableNicknameSearch && searchType == ProtoConstants.SearchUserType.SearchUserType_General) {
|
||||
@@ -3093,10 +3343,29 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
|
||||
if(mDisableUserIdSearch && searchType == ProtoConstants.SearchUserType.SearchUserType_UserId) {
|
||||
return new ArrayList<>();
|
||||
return ErrorCode.ERROR_CODE_NOT_IMPLEMENT;
|
||||
}
|
||||
|
||||
return databaseStore.searchUserFromDB(keyword, searchType, page);
|
||||
if(mFriendSearchRateLimiter != null && !isPhoneNumberPart(keyword)) {
|
||||
//非电话号码,允许多少次搜索。
|
||||
if(!mFriendSearchRateLimiter.isGranted(userId)) {
|
||||
LOG.error("User {} search user mobile over frequency, keyword {}, searchType {}", userId, keyword, searchType);
|
||||
return ErrorCode.ERROR_CODE_OVER_FREQUENCY;
|
||||
}
|
||||
}
|
||||
|
||||
List<WFCMessage.User> matchedUsers = databaseStore.searchUserFromDB(keyword, searchType, userType, page);
|
||||
if(mFriendSearchEmpthMobileRateLimiter != null && matchedUsers.isEmpty() && isPhoneNumber(keyword)) {
|
||||
//查电话号码为空
|
||||
if(!mFriendSearchEmpthMobileRateLimiter.isGranted(userId)) {
|
||||
LOG.error("User {} search user over frequency, keyword {}, searchType {}", userId, keyword, searchType);
|
||||
return ErrorCode.ERROR_CODE_OVER_FREQUENCY;
|
||||
}
|
||||
}
|
||||
|
||||
users.addAll(matchedUsers);
|
||||
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3819,6 +4088,25 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return ErrorCode.ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowName(String name) {
|
||||
if(StringUtil.isNullOrEmpty(name)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
name = name.trim();
|
||||
SystemSettingPojo notAllowNameSetting = getSystemSetting(ProtoConstants.SystemSettingType.NOT_ALLOW_USER_NAMES);
|
||||
if (notAllowNameSetting != null && !StringUtil.isNullOrEmpty(notAllowNameSetting.value)) {
|
||||
String[] ss = notAllowNameSetting.value.split(",");
|
||||
for (String s : ss) {
|
||||
if(name.contains(s.trim())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode handleJoinChatroom(String userId, String clientId, String chatroomId) {
|
||||
IMap<String, WFCMessage.ChatroomInfo> chatroomInfoMap = m_Server.getHazelcastInstance().getMap(CHATROOMS);
|
||||
@@ -4292,6 +4580,15 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocked(String userId, String clientId) {
|
||||
WFCMessage.UserSettingEntry lockSetting = getUserSetting(userId, UserSettingScopeLockPC, clientId);
|
||||
if(lockSetting != null && "1".equals(lockSetting.getValue())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getUserGlobalSilent(String userId) {
|
||||
Boolean slient = userGlobalSlientMap.get(userId);
|
||||
@@ -4458,7 +4755,7 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
} else if(modifyType == Modify_Channel_Menu) {
|
||||
OutputGetChannelInfo.OutputMenuList outputMenuButtons = GsonUtil.gson.fromJson(value, OutputGetChannelInfo.OutputMenuList.class);
|
||||
if (!outputMenuButtons.isEmpty()) {
|
||||
for (OutputGetChannelInfo.OutputMenu outputMenuButton : outputMenuButtons) {
|
||||
for (PojoChannelMenu outputMenuButton : outputMenuButtons) {
|
||||
newInfoBuilder.addMenu(outputMenuButton.toPbInfo());
|
||||
}
|
||||
}
|
||||
@@ -4688,6 +4985,11 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return new ArrayList<>(databaseStore.getSensitiveWord());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSensitiveOnlyMessage() {
|
||||
return mSensitiveOnlyMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WFCMessage.Message getMessage(long messageId) {
|
||||
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
|
||||
@@ -4714,6 +5016,11 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return mGroupVisibleQuitKickoffNotification;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGroupAllowPartSuccess() {
|
||||
return mGroupAllowPartSuccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGroupForbiddenClientOperation() {
|
||||
return mGroupForbiddenClientOperation;
|
||||
@@ -4724,16 +5031,56 @@ public class MemoryMessagesStore implements IMessagesStore {
|
||||
return mForwardMessageWithClientInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForwardMessageWithSenderInfo() {
|
||||
return mForwardMessageWithSenderInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForwardMessageWithTargetInfo() {
|
||||
return mForwardMessageWithTargetInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRobotCallbackWithClientInfo() {
|
||||
return mRobotCallbackWithClientInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRobotCallbackWithSenderInfo() {
|
||||
return mRobotCallbackWithSenderInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRobotCallbackWithTargetInfo() {
|
||||
return mRobotCallbackWithTargetInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRobotMentionExternalRobot() {
|
||||
return mRobotMentionExternalRobot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRobotGetUserInfoMask() {
|
||||
return mRobotGetUserInfoMask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChannelCallbackWithClientInfo() {
|
||||
return mChannelCallbackWithClientInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChannelCallbackWithSenderInfo() {
|
||||
return mChannelCallbackWithSenderInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChannelCallbackWithTargetInfo() {
|
||||
return mChannelCallbackWithTargetInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChannelNewCallbackFeature() {
|
||||
return mChannelNewCallbackFeature;
|
||||
|
||||
@@ -41,6 +41,8 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
private boolean supportMultiEndpoint = false;
|
||||
private boolean supportMultiPCEndpoint = false;
|
||||
private boolean supportMultiPadEndpoint = false;
|
||||
private boolean supportMultiWearableEndpoint = false;
|
||||
private boolean supportMultiTVEndpoint = false;
|
||||
private boolean clientSupportKickoff = false;
|
||||
|
||||
public static class Session implements Comparable<Session>{
|
||||
@@ -61,6 +63,7 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
private int deleted;
|
||||
|
||||
private boolean pullHistoryMsg;
|
||||
private String ip;
|
||||
|
||||
public int getDeleted() {
|
||||
return deleted;
|
||||
@@ -92,8 +95,16 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
return unReceivedMsgs;
|
||||
}
|
||||
|
||||
public void setUnReceivedMsgs(int unReceivedMsgs) {
|
||||
this.unReceivedMsgs = unReceivedMsgs;
|
||||
public boolean isPcClient() {
|
||||
return platform == ProtoConstants.Platform.Platform_Windows || platform == ProtoConstants.Platform.Platform_OSX || platform == ProtoConstants.Platform.Platform_LINUX;
|
||||
}
|
||||
|
||||
public boolean isPadClient() {
|
||||
return platform == ProtoConstants.Platform.Platform_iPad || platform == ProtoConstants.Platform.Platform_APad || platform == ProtoConstants.Platform.Platform_HarmonyPad;
|
||||
}
|
||||
|
||||
public boolean isTVClient() {
|
||||
return platform == ProtoConstants.Platform.Platform_AppleTV || platform == ProtoConstants.Platform.Platform_AndroidTV || platform == ProtoConstants.Platform.Platform_HarmonyTV;
|
||||
}
|
||||
|
||||
public int getPushType() {
|
||||
@@ -163,6 +174,14 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
}
|
||||
}
|
||||
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
public void setIp(String ip) {
|
||||
this.ip = ip;
|
||||
}
|
||||
|
||||
private int pushType;
|
||||
private int platform;
|
||||
|
||||
@@ -298,6 +317,16 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
try {
|
||||
supportMultiWearableEndpoint = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_MULTI_WEARABLE_ENDPOINT, "false"));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
try {
|
||||
supportMultiTVEndpoint = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_MULTI_TV_ENDPOINT, "false"));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
try {
|
||||
clientSupportKickoff = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_CLIENT_SUPPORT_KICKOFF_EVENT, "false"));
|
||||
} catch (Exception e) {
|
||||
@@ -405,6 +434,11 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
&& !(platform == ProtoConstants.Platform.Platform_iPad && supportMultiPadEndpoint)
|
||||
&& !(platform == ProtoConstants.Platform.Platform_APad && supportMultiPadEndpoint)
|
||||
&& !(platform == ProtoConstants.Platform.Platform_HarmonyPad && supportMultiPadEndpoint)
|
||||
&& !(platform == ProtoConstants.Platform.Platform_AndroidWearable && supportMultiWearableEndpoint)
|
||||
&& !(platform == ProtoConstants.Platform.Platform_HarmonyWearable && supportMultiWearableEndpoint)
|
||||
&& !(platform == ProtoConstants.Platform.Platform_AndroidTV && supportMultiTVEndpoint)
|
||||
&& !(platform == ProtoConstants.Platform.Platform_AppleTV && supportMultiTVEndpoint)
|
||||
&& !(platform == ProtoConstants.Platform.Platform_HarmonyTV && supportMultiTVEndpoint)
|
||||
) {
|
||||
databaseStore.clearMultiEndpoint(username, clientID, platform);
|
||||
if (userSessions.get(username) != null) {
|
||||
@@ -431,6 +465,14 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
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 if(platform == ProtoConstants.Platform.Platform_AndroidWearable || platform == ProtoConstants.Platform.Platform_HarmonyWearable) {
|
||||
if (s.getPlatform() == ProtoConstants.Platform.Platform_AndroidWearable || s.getPlatform() == ProtoConstants.Platform.Platform_HarmonyWearable) {
|
||||
remove = true;
|
||||
}
|
||||
} else if(platform == ProtoConstants.Platform.Platform_AndroidTV || platform == ProtoConstants.Platform.Platform_AppleTV || platform == ProtoConstants.Platform.Platform_HarmonyTV) {
|
||||
if (s.getPlatform() == ProtoConstants.Platform.Platform_AndroidTV || s.getPlatform() == ProtoConstants.Platform.Platform_AppleTV || s.getPlatform() == ProtoConstants.Platform.Platform_HarmonyTV) {
|
||||
remove = true;
|
||||
}
|
||||
} else { //web, microapp
|
||||
if (s.getPlatform() ==platform) {
|
||||
remove = true;
|
||||
@@ -548,6 +590,15 @@ public class MemorySessionStore implements ISessionsStore {
|
||||
return session.clientSession;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSessionIp(String username, String clientID, String ip) {
|
||||
Session session = getSession(clientID);
|
||||
if(session != null && session.getDeleted() == 0) {
|
||||
session.setIp(ip);
|
||||
databaseStore.updateSessionIp(username, clientID, ip);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session sessionForClientAndUser(String username, String clientID) {
|
||||
Session session = sessions.get(clientID);
|
||||
|
||||
@@ -331,6 +331,17 @@ public class Server {
|
||||
MediaServerConfig.QINIU_BUCKET_FAVORITE_NAME = config.getProperty(BrokerConstants.QINIU_BUCKET_FAVORITE_NAME);
|
||||
MediaServerConfig.QINIU_BUCKET_FAVORITE_DOMAIN = config.getProperty(BrokerConstants.QINIU_BUCKET_FAVORITE_DOMAIN);
|
||||
|
||||
MediaServerConfig.QINIU_BUCKET_CUSTOM1_NAME = config.getProperty(BrokerConstants.QINIU_BUCKET_CUSTOM1_NAME);
|
||||
MediaServerConfig.QINIU_BUCKET_CUSTOM1_DOMAIN = config.getProperty(BrokerConstants.QINIU_BUCKET_CUSTOM1_DOMAIN);
|
||||
|
||||
MediaServerConfig.QINIU_BUCKET_CUSTOM2_NAME = config.getProperty(BrokerConstants.QINIU_BUCKET_CUSTOM2_NAME);
|
||||
MediaServerConfig.QINIU_BUCKET_CUSTOM2_DOMAIN = config.getProperty(BrokerConstants.QINIU_BUCKET_CUSTOM2_DOMAIN);
|
||||
|
||||
MediaServerConfig.QINIU_BUCKET_CUSTOM3_NAME = config.getProperty(BrokerConstants.QINIU_BUCKET_CUSTOM3_NAME);
|
||||
MediaServerConfig.QINIU_BUCKET_CUSTOM3_DOMAIN = config.getProperty(BrokerConstants.QINIU_BUCKET_CUSTOM3_DOMAIN);
|
||||
|
||||
MediaServerConfig.QINIU_BUCKET_PAN_NAME = config.getProperty(BrokerConstants.QINIU_BUCKET_PAN_NAME);
|
||||
MediaServerConfig.QINIU_BUCKET_PAN_DOMAIN = config.getProperty(BrokerConstants.QINIU_BUCKET_PAN_DOMAIN);
|
||||
|
||||
MediaServerConfig.SERVER_IP = getServerIp(config);
|
||||
|
||||
|
||||
@@ -23,7 +23,16 @@ public class MediaServerConfig {
|
||||
public static String QINIU_BUCKET_PORTRAIT_DOMAIN;
|
||||
public static String QINIU_BUCKET_FAVORITE_NAME;
|
||||
public static String QINIU_BUCKET_FAVORITE_DOMAIN;
|
||||
|
||||
public static String QINIU_BUCKET_CUSTOM1_NAME;
|
||||
public static String QINIU_BUCKET_CUSTOM1_DOMAIN;
|
||||
public static String QINIU_BUCKET_CUSTOM2_NAME;
|
||||
public static String QINIU_BUCKET_CUSTOM2_DOMAIN;
|
||||
public static String QINIU_BUCKET_CUSTOM3_NAME;
|
||||
public static String QINIU_BUCKET_CUSTOM3_DOMAIN;
|
||||
public static String QINIU_BUCKET_PAN_NAME;
|
||||
public static String QINIU_BUCKET_PAN_DOMAIN;
|
||||
|
||||
|
||||
public static String SERVER_IP = "localhost";
|
||||
public static int HTTP_SERVER_PORT = 8080;
|
||||
public static String FILE_STROAGE_ROOT = "fs";
|
||||
|
||||
@@ -102,9 +102,9 @@ public interface IMessagesStore {
|
||||
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);
|
||||
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);
|
||||
ErrorCode addGroupMembers(String operator, boolean isAdmin, String groupId, List<WFCMessage.GroupMember> memberList, String extra);
|
||||
ErrorCode canAddGroupMembers(String operator, List<WFCMessage.GroupMember> memberList, Map<String, Integer> failedMembers);
|
||||
WFCMessage.GroupInfo createGroup(String operator, WFCMessage.GroupInfo groupInfo, List<WFCMessage.GroupMember> memberList, String memberExtra, boolean isAdmin, Map<String, Integer> failedMembers);
|
||||
ErrorCode addGroupMembers(String operator, boolean isAdmin, String groupId, List<WFCMessage.GroupMember> memberList, String extra, Map<String, Integer> failedMembers);
|
||||
ErrorCode kickoffGroupMembers(String operator, boolean isAdmin, String groupId, List<String> memberList);
|
||||
ErrorCode quitGroup(String operator, String groupId, boolean admin);
|
||||
void clearUserGroups(String userId);
|
||||
@@ -154,9 +154,12 @@ public interface IMessagesStore {
|
||||
WFCMessage.User getUserInfoByName(String name);
|
||||
WFCMessage.User getUserInfoByMobile(String mobile);
|
||||
List<WFCMessage.User> getUserInfosByEmail(String email);
|
||||
List<WFCMessage.User> searchUser(String keyword, int searchType, int page);
|
||||
List<WFCMessage.User> getUserInfosByMobile(String mobile, boolean includeDeleted);
|
||||
ErrorCode searchUser(String userId, String keyword, int searchType, int userType, int page, List<WFCMessage.User> users);
|
||||
|
||||
List<WFCMessage.User> getUserInfoList(int count, int offset);
|
||||
List<WFCMessage.Robot> getRobotInfoList(int count, int offset);
|
||||
List<String> getUserRobotIds(String userId);
|
||||
|
||||
boolean updateSystemSetting(int id, String value, String desc);
|
||||
SystemSettingPojo getSystemSetting(int id);
|
||||
@@ -190,6 +193,8 @@ public interface IMessagesStore {
|
||||
ErrorCode setFriendAliasRequest(String fromUser, String targetUserId, String alias, long[] head);
|
||||
ErrorCode setFriendExtraRequest(String fromUser, String targetUserId, String extra, long[] head);
|
||||
|
||||
boolean isAllowName(String name);
|
||||
|
||||
ErrorCode handleJoinChatroom(String userId, String clientId, String chatroomId);
|
||||
ErrorCode handleQuitChatroom(String userId, String clientId, String chatroomId);
|
||||
|
||||
@@ -205,6 +210,9 @@ public interface IMessagesStore {
|
||||
List<WFCMessage.UserSettingEntry> getUserSetting(String userId, int scope);
|
||||
long updateUserSettings(String userId, WFCMessage.ModifyUserSettingReq request, String clientId);
|
||||
void clearUserSettings(String userId);
|
||||
|
||||
boolean isLocked(String userId, String clientId);
|
||||
|
||||
boolean getUserGlobalSilent(String userId);
|
||||
boolean getUserVoipSilent(String userId);
|
||||
|
||||
@@ -232,9 +240,13 @@ public interface IMessagesStore {
|
||||
boolean addSensitiveWords(List<String> words);
|
||||
boolean removeSensitiveWords(List<String> words);
|
||||
List<String> getAllSensitiveWords();
|
||||
boolean isSensitiveOnlyMessage();
|
||||
|
||||
WFCMessage.Message getMessage(long messageId);
|
||||
|
||||
void increaseUnreceivedMsgCount(String user);
|
||||
int getUnreceivedMsgCount(String user);
|
||||
|
||||
boolean isAllowClientCustomGroupNotification();
|
||||
boolean isAllowRobotCustomGroupNotification();
|
||||
int getVisibleQuitKickoffNotification();
|
||||
@@ -242,10 +254,20 @@ public interface IMessagesStore {
|
||||
int getGroupForbiddenClientOperation();
|
||||
|
||||
boolean isForwardMessageWithClientInfo();
|
||||
boolean isRobotCallbackWithClientInfo();
|
||||
boolean isChannelCallbackWithClientInfo();
|
||||
boolean isChannelNewCallbackFeature();
|
||||
boolean isForwardMessageWithSenderInfo();
|
||||
boolean isForwardMessageWithTargetInfo();
|
||||
|
||||
boolean isRobotCallbackWithClientInfo();
|
||||
boolean isRobotCallbackWithSenderInfo();
|
||||
boolean isRobotCallbackWithTargetInfo();
|
||||
boolean isRobotMentionExternalRobot();
|
||||
int getRobotGetUserInfoMask();
|
||||
|
||||
boolean isChannelCallbackWithClientInfo();
|
||||
boolean isChannelCallbackWithSenderInfo();
|
||||
boolean isChannelCallbackWithTargetInfo();
|
||||
boolean isChannelNewCallbackFeature();
|
||||
boolean isGroupAllowPartSuccess();
|
||||
boolean isRobotAutoAcceptFriendRequest();
|
||||
|
||||
long getPushExpiredTimes();
|
||||
|
||||
@@ -43,7 +43,7 @@ public interface ISessionsStore {
|
||||
ErrorCode loadActiveSession(String username, String clientID);
|
||||
|
||||
ClientSession updateExistSession(String username, String clientID, WFCMessage.RouteRequest endpoint, boolean cleanSession);
|
||||
|
||||
void updateSessionIp(String username, String clientID, String ip);
|
||||
Session getSession(String clientID);
|
||||
|
||||
void cleanDuplatedToken(String cid, int pushType, String token, boolean isVoip, String packageName);
|
||||
|
||||
@@ -16,14 +16,13 @@
|
||||
|
||||
package io.moquette.spi.impl;
|
||||
|
||||
import cn.wildfirechat.pojos.OutputClient;
|
||||
import cn.wildfirechat.pojos.OutputMessageData;
|
||||
import org.json.simple.JSONObject;
|
||||
import cn.wildfirechat.pojos.*;
|
||||
import cn.wildfirechat.proto.ProtoConstants;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import cn.wildfirechat.push.PushServer;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import com.hazelcast.util.StringUtil;
|
||||
import cn.wildfirechat.pojos.OutputNotifyChannelSubscribeStatus;
|
||||
import com.xiaoleilu.loServer.model.FriendData;
|
||||
import io.moquette.persistence.*;
|
||||
import io.moquette.persistence.MemorySessionStore.Session;
|
||||
@@ -34,12 +33,14 @@ import io.moquette.spi.ISessionsStore;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.mqtt.*;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import win.liyufan.im.*;
|
||||
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@@ -47,6 +48,7 @@ import java.util.concurrent.Executors;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import static cn.wildfirechat.common.IMExceptionEvent.EventType.EVENT_CALLBACK_Exception;
|
||||
import static cn.wildfirechat.proto.ProtoConstants.ConversationType.*;
|
||||
import static cn.wildfirechat.proto.ProtoConstants.PersistFlag.Transparent;
|
||||
|
||||
public class MessagesPublisher {
|
||||
@@ -157,7 +159,7 @@ public class MessagesPublisher {
|
||||
}
|
||||
}
|
||||
|
||||
private void publish2Receivers(String sender, int conversationType, String target, int line, long messageId, Collection<String> receivers, String pushContent, String pushData, String exceptClientId, int pullType, int messageContentType, long serverTime, int mentionType, List<String> mentionTargets, int persistFlag, boolean directing) {
|
||||
private void publish2Receivers(String sender, int conversationType, String target, int line, long messageId, Collection<String> receivers, String pushContent, String pushData, long callStartUid, String exceptClientId, int pullType, int messageContentType, long serverTime, int mentionType, List<String> mentionTargets, int persistFlag, boolean directing) {
|
||||
if (persistFlag == Transparent) {
|
||||
publishTransparentMessage2Receivers(messageId, receivers, pullType, exceptClientId);
|
||||
return;
|
||||
@@ -176,19 +178,11 @@ public class MessagesPublisher {
|
||||
if (message == null) {
|
||||
message = m_messagesStore.getMessage(messageId);
|
||||
}
|
||||
OutputClient outputClient = null;
|
||||
if(m_messagesStore.isRobotCallbackWithClientInfo() && !StringUtil.isNullOrEmpty(exceptClientId)) {
|
||||
Session session = m_sessionsStore.getSession(exceptClientId);
|
||||
if(session != null && session.getUsername().equals(sender)) {
|
||||
outputClient = new OutputClient(session.getPlatform(), exceptClientId);
|
||||
}
|
||||
}
|
||||
|
||||
final WFCMessage.Message finalMsg = message;
|
||||
OutputClient finalOutputClient = outputClient;
|
||||
OutputMessageData outputMessageData = getOutputMessageWithExtraInfo(message, exceptClientId, m_messagesStore.isRobotCallbackWithClientInfo() , m_messagesStore.isRobotCallbackWithSenderInfo(), m_messagesStore.isRobotCallbackWithTargetInfo());
|
||||
outputMessageData.setToRobotId(robot.getUid());
|
||||
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);
|
||||
HttpUtils.httpJsonPost(robot.getCallback(), GsonUtil.gson.toJson(outputMessageData, OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Robot_Message_Callback);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
|
||||
@@ -237,6 +231,7 @@ public class MessagesPublisher {
|
||||
}
|
||||
}
|
||||
|
||||
boolean unreadCountIncreased = false;
|
||||
for (Session targetSession : sessions) {
|
||||
//超过7天不活跃的用户忽略
|
||||
if(System.currentTimeMillis() - targetSession.getLastActiveTime() > m_messagesStore.getPushExpiredTimes()) {
|
||||
@@ -283,7 +278,7 @@ public class MessagesPublisher {
|
||||
|
||||
if (!user.equals(sender)) {
|
||||
WFCMessage.Conversation conversation;
|
||||
if (conversationType == ProtoConstants.ConversationType.ConversationType_Private) {
|
||||
if (conversationType == ConversationType_Private) {
|
||||
conversation = WFCMessage.Conversation.newBuilder().setType(conversationType).setLine(line).setTarget(sender).build();
|
||||
} else {
|
||||
conversation = WFCMessage.Conversation.newBuilder().setType(conversationType).setLine(line).setTarget(target).build();
|
||||
@@ -321,8 +316,9 @@ public class MessagesPublisher {
|
||||
}
|
||||
|
||||
if (!StringUtil.isNullOrEmpty(pushContent) || messageContentType == 400) {
|
||||
if (!isConvSilent && (persistFlag & 0x02) > 0) {
|
||||
targetSession.setUnReceivedMsgs(targetSession.getUnReceivedMsgs() + 1);
|
||||
if (!isConvSilent && (persistFlag & 0x02) > 0 && !unreadCountIncreased) {
|
||||
m_messagesStore.increaseUnreceivedMsgCount(user);
|
||||
unreadCountIncreased = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -398,7 +394,7 @@ public class MessagesPublisher {
|
||||
|
||||
if(!sendNameLoaded) {
|
||||
List<String> list = new ArrayList<>();
|
||||
senderName = getUserDisplayName(sender, conversationType == ProtoConstants.ConversationType.ConversationType_Group ? target : null, list);
|
||||
senderName = getUserDisplayName(sender, conversationType == ConversationType_Group ? target : null, list);
|
||||
if(!list.isEmpty()) {
|
||||
senderPortrait = list.get(0);
|
||||
}
|
||||
@@ -421,13 +417,25 @@ public class MessagesPublisher {
|
||||
name = fd.getAlias();
|
||||
}
|
||||
}
|
||||
this.messageSender.sendPush(sender, conversationType, target, line, messageId, targetSession.getClientID(), pushContent, pushData, messageContentType, serverTime, name, senderPortrait, targetName, targetPortrait, targetSession.getUnReceivedMsgs(), curMentionType, isHiddenDetail, targetSession.getLanguage());
|
||||
|
||||
this.messageSender.sendPush(sender, conversationType, target, line, messageId, targetSession.getClientID(), pushContent, pushData, callStartUid, messageContentType, serverTime, name, senderPortrait, targetName, targetPortrait, m_messagesStore.getUnreceivedMsgCount(user), curMentionType, isHiddenDetail, targetSession.getLanguage(), getExistBadgeNumber(user));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int getExistBadgeNumber(String user) {
|
||||
int existBadgeNumber = 0;
|
||||
WFCMessage.UserSettingEntry userSettingData = m_messagesStore.getUserSetting(user, UserSettingScope.kUserSettingScopeSyncBadge, "");
|
||||
if(userSettingData != null && !StringUtil.isNullOrEmpty(userSettingData.getValue())) {
|
||||
try {
|
||||
existBadgeNumber = Integer.parseInt(userSettingData.getValue());
|
||||
} catch (NumberFormatException e) {}
|
||||
}
|
||||
return existBadgeNumber;
|
||||
}
|
||||
|
||||
public boolean sendOfflineNotify(String clientId) {
|
||||
boolean targetIsActive = this.connectionDescriptors.isConnected(clientId);
|
||||
if (targetIsActive) {
|
||||
@@ -486,19 +494,10 @@ public class MessagesPublisher {
|
||||
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;
|
||||
OutputMessageData outputMessageData = getOutputMessageWithExtraInfo(message, exceptClientId, m_messagesStore.isRobotCallbackWithClientInfo() , m_messagesStore.isRobotCallbackWithSenderInfo(), m_messagesStore.isRobotCallbackWithTargetInfo());
|
||||
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);
|
||||
HttpUtils.httpJsonPost(robot.getCallback(), GsonUtil.gson.toJson(outputMessageData, OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Robot_Message_Callback);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
|
||||
@@ -530,9 +529,9 @@ public class MessagesPublisher {
|
||||
}
|
||||
|
||||
String getTargetName(String targetId, int cnvType, String fromUser, List<String> portraitList) {
|
||||
if (cnvType == ProtoConstants.ConversationType.ConversationType_Private) {
|
||||
if (cnvType == ConversationType_Private) {
|
||||
return getUserDisplayName(targetId, null, portraitList);
|
||||
} else if(cnvType == ProtoConstants.ConversationType.ConversationType_Group) {
|
||||
} else if(cnvType == ConversationType_Group) {
|
||||
WFCMessage.GroupInfo group = m_messagesStore.getGroupInfo(targetId);
|
||||
if(group != null) {
|
||||
if(!StringUtil.isNullOrEmpty(group.getPortrait())) {
|
||||
@@ -545,7 +544,7 @@ public class MessagesPublisher {
|
||||
}
|
||||
return group.getName();
|
||||
}
|
||||
} else if(cnvType == ProtoConstants.ConversationType.ConversationType_Channel) {
|
||||
} else if(cnvType == ConversationType_Channel) {
|
||||
WFCMessage.ChannelInfo channelInfo = m_messagesStore.getChannelInfo(targetId);
|
||||
if (channelInfo != null) {
|
||||
if(!StringUtil.isNullOrEmpty(channelInfo.getPortrait())) {
|
||||
@@ -602,7 +601,7 @@ public class MessagesPublisher {
|
||||
}
|
||||
|
||||
if (IMTopic.NotifyFriendRequestTopic.equals(topic)) {
|
||||
messageSender.sendPush(fromUser, receiver, targetSession.getClientID(), pushContent, PushServer.PushMessageType.PUSH_MESSAGE_TYPE_FRIEND_REQUEST, System.currentTimeMillis(), fromUserName, targetSession.getUnReceivedMsgs() + 1, targetSession.getLanguage());
|
||||
messageSender.sendPush(fromUser, receiver, targetSession.getClientID(), pushContent, PushServer.PushMessageType.PUSH_MESSAGE_TYPE_FRIEND_REQUEST, System.currentTimeMillis(), fromUserName, m_messagesStore.getUnreceivedMsgCount(receiver) + 1, targetSession.getLanguage(), getExistBadgeNumber(receiver));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -667,7 +666,7 @@ public class MessagesPublisher {
|
||||
}
|
||||
|
||||
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() == ConversationType_Channel) {
|
||||
WFCMessage.ChannelInfo channelInfo = m_messagesStore.getChannelInfo(message.getConversation().getTarget());
|
||||
|
||||
boolean forwardMsg;
|
||||
@@ -678,18 +677,10 @@ public class MessagesPublisher {
|
||||
}
|
||||
|
||||
if (forwardMsg) {
|
||||
OutputClient outputClient = null;
|
||||
if(m_messagesStore.isChannelCallbackWithClientInfo() && !StringUtil.isNullOrEmpty(exceptClientId)) {
|
||||
Session session = m_sessionsStore.getSession(exceptClientId);
|
||||
if(session != null && session.getUsername().equals(message.getFromUser())) {
|
||||
outputClient = new OutputClient(session.getPlatform(), exceptClientId);
|
||||
}
|
||||
}
|
||||
|
||||
OutputClient finalOutputClient = outputClient;
|
||||
OutputMessageData outputMessageData = getOutputMessageWithExtraInfo(message, exceptClientId, m_messagesStore.isChannelCallbackWithClientInfo() , m_messagesStore.isChannelCallbackWithSenderInfo(), m_messagesStore.isChannelCallbackWithTargetInfo());
|
||||
Server.getServer().getCallbackScheduler().execute(() -> {
|
||||
try {
|
||||
HttpUtils.httpJsonPost(channelInfo.getCallback() + "/message", GsonUtil.gson.toJson(OutputMessageData.fromProtoMessage(message, finalOutputClient), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Channel_Message_Callback);
|
||||
HttpUtils.httpJsonPost(channelInfo.getCallback() + "/message", GsonUtil.gson.toJson(outputMessageData, OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Channel_Message_Callback);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
|
||||
@@ -733,18 +724,92 @@ public class MessagesPublisher {
|
||||
pushContent = null;
|
||||
}
|
||||
|
||||
long callStartUid = 0;
|
||||
if (message.getContent().getType() == 402) {
|
||||
try {
|
||||
String str = new String(message.getContent().getData().toByteArray(), StandardCharsets.UTF_8);
|
||||
JSONObject jsonObject = (JSONObject)(new JSONParser().parse(str));
|
||||
if (jsonObject.containsKey("u")) {
|
||||
callStartUid = (Long)jsonObject.get("u");
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
|
||||
publish2Receivers(message.getFromUser(),
|
||||
message.getConversation().getType(), message.getConversation().getTarget(), message.getConversation().getLine(),
|
||||
messageId,
|
||||
receivers,
|
||||
pushContent, message.getContent().getPushData(), exceptClientId, pullType, message.getContent().getType(), message.getServerTimestamp(), message.getContent().getMentionedType(), message.getContent().getMentionedTargetList(), message.getContent().getPersistFlag(), message.hasToUser() || !message.getToList().isEmpty());
|
||||
pushContent, message.getContent().getPushData(), callStartUid, exceptClientId, pullType, message.getContent().getType(), message.getServerTimestamp(), message.getContent().getMentionedType(), message.getContent().getMentionedTargetList(), message.getContent().getPersistFlag(), message.hasToUser() || !message.getToList().isEmpty());
|
||||
|
||||
}
|
||||
|
||||
public void forwardMessage(final WFCMessage.Message message, String forwardUrl, OutputClient outputClient) {
|
||||
private OutputMessageData getOutputMessageWithExtraInfo(WFCMessage.Message message, String clientId, boolean withClient, boolean withSender, boolean withTarget) {
|
||||
if (message == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
OutputClient outputClient = null;
|
||||
if (withClient && !StringUtil.isNullOrEmpty(clientId)) {
|
||||
Session session = m_sessionsStore.getSession(clientId);
|
||||
if(session != null && session.getUsername().equals(message.getFromUser())) {
|
||||
outputClient = new OutputClient(session.getPlatform(), clientId);
|
||||
}
|
||||
}
|
||||
|
||||
OutputMessageData outputMessageData = OutputMessageData.fromProtoMessage(message, outputClient);
|
||||
if (withSender) {
|
||||
WFCMessage.User senderInfo = m_messagesStore.getUserInfo(message.getFromUser());
|
||||
outputMessageData.setSenderUserInfo(InputOutputUserInfo.fromPbUser(senderInfo));
|
||||
}
|
||||
|
||||
if (withTarget) {
|
||||
if (message.getConversation().getType() == ConversationType_Private) {
|
||||
WFCMessage.User targetInfo = m_messagesStore.getUserInfo(message.getConversation().getTarget());
|
||||
if (targetInfo != null) {
|
||||
outputMessageData.setTargetUserInfo(InputOutputUserInfo.fromPbUser(targetInfo));
|
||||
}
|
||||
} else if(message.getConversation().getType() == ConversationType_Group) {
|
||||
WFCMessage.GroupInfo groupInfo = m_messagesStore.getGroupInfo(message.getConversation().getTarget());
|
||||
if (groupInfo != null) {
|
||||
PojoGroupInfo pojoGroupInfo = new PojoGroupInfo();
|
||||
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.setMember_count(groupInfo.getMemberCount());
|
||||
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);
|
||||
pojoGroupInfo.setDeleted(groupInfo.getDeleted()>0);
|
||||
pojoGroupInfo.setUpdate_dt(groupInfo.getUpdateDt());
|
||||
pojoGroupInfo.setMember_update_dt(groupInfo.getMemberUpdateDt());
|
||||
outputMessageData.setTargetGroupInfo(pojoGroupInfo);
|
||||
}
|
||||
} else if(message.getConversation().getType() == ConversationType_Channel) {
|
||||
WFCMessage.ChannelInfo targetInfo = m_messagesStore.getChannelInfo(message.getConversation().getTarget());
|
||||
if (targetInfo != null) {
|
||||
outputMessageData.setTargetChannelInfo(OutputGetChannelInfo.fromPbInfo(targetInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return outputMessageData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void forwardMessage(final WFCMessage.Message message, String forwardUrl, String fromClientId) {
|
||||
OutputMessageData outputMessageData = getOutputMessageWithExtraInfo(message, fromClientId, m_messagesStore.isForwardMessageWithClientInfo() , m_messagesStore.isForwardMessageWithSenderInfo(), m_messagesStore.isForwardMessageWithTargetInfo());
|
||||
Server.getServer().getCallbackScheduler().execute(() -> {
|
||||
try {
|
||||
HttpUtils.httpJsonPost(forwardUrl, GsonUtil.gson.toJson(OutputMessageData.fromProtoMessage(message, outputClient), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Forward_Message_Callback);
|
||||
HttpUtils.httpJsonPost(forwardUrl, GsonUtil.gson.toJson(outputMessageData), HttpUtils.HttpPostType.POST_TYPE_Forward_Message_Callback);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
|
||||
@@ -752,9 +817,10 @@ public class MessagesPublisher {
|
||||
});
|
||||
}
|
||||
|
||||
public void forwardMessageWithCallback(final WFCMessage.Message message, String forwardUrl, HttpUtils.HttpCallback callback) {
|
||||
public void forwardMessageWithCallback(final WFCMessage.Message message, String fromClientId, String forwardUrl, HttpUtils.HttpCallback callback) {
|
||||
OutputMessageData outputMessageData = getOutputMessageWithExtraInfo(message, fromClientId, m_messagesStore.isForwardMessageWithClientInfo() , m_messagesStore.isForwardMessageWithSenderInfo(), m_messagesStore.isForwardMessageWithTargetInfo());
|
||||
try {
|
||||
HttpUtils.httpJsonPost(forwardUrl, GsonUtil.gson.toJson(OutputMessageData.fromProtoMessage(message), OutputMessageData.class), new HttpUtils.HttpCallback() {
|
||||
HttpUtils.httpJsonPost(forwardUrl, GsonUtil.gson.toJson(outputMessageData), new HttpUtils.HttpCallback() {
|
||||
@Override
|
||||
public void onSuccess(String content) {
|
||||
Server.getServer().getImBusinessScheduler().execute(()->{
|
||||
|
||||
@@ -37,16 +37,18 @@ class PersistentQueueMessageSender {
|
||||
this.connectionDescriptorStore = connectionDescriptorStore;
|
||||
}
|
||||
|
||||
void sendPush(String sender, int conversationType, String target, int line, long messageId, String deviceId, String pushContent, String pushData, int messageContentType, long serverTime, String senderName, String senderPortrait, String targetName, String targetPortrait, int unReceivedMsg, int mentionType, boolean isHiddenDetail, String language) {
|
||||
void sendPush(String sender, int conversationType, String target, int line, long messageId, String deviceId, String pushContent, String pushData, long callStartUid, int messageContentType, long serverTime, String senderName, String senderPortrait, String targetName, String targetPortrait, int unReceivedMsg, int mentionType, boolean isHiddenDetail, String language, int existBadgeNumber) {
|
||||
LOG.info("Send push to {}, message from {}", deviceId, sender);
|
||||
PushMessage pushMessage = new PushMessage(sender, conversationType, target, line, messageContentType, serverTime, senderName, senderPortrait, targetName, targetPortrait, unReceivedMsg, mentionType, isHiddenDetail, language);
|
||||
pushMessage.pushContent = pushContent;
|
||||
pushMessage.pushData = pushData;
|
||||
pushMessage.messageId = messageId;
|
||||
pushMessage.callStartUid = callStartUid;
|
||||
pushMessage.existBadgeNumber = existBadgeNumber;
|
||||
PushServer.getServer().pushMessage(pushMessage, deviceId, pushContent);
|
||||
}
|
||||
|
||||
void sendPush(String sender, String target, String deviceId, String pushContent, int pushContentType, long serverTime, String senderName, int unReceivedMsg, String language) {
|
||||
void sendPush(String sender, String target, String deviceId, String pushContent, int pushContentType, long serverTime, String senderName, int unReceivedMsg, String language, int existBadgeNumber) {
|
||||
LOG.info("Send push to {}, message from {}", deviceId, sender);
|
||||
PushMessage pushMessage = new PushMessage(sender, target, serverTime, senderName, unReceivedMsg, language, pushContentType);
|
||||
pushMessage.pushContent = pushContent;
|
||||
|
||||
@@ -284,7 +284,7 @@ public class ProtocolProcessor {
|
||||
sessionstatus = 0;
|
||||
}
|
||||
|
||||
userOnlineStatus.sessions.add(new OutputCheckUserOnline.Session(userId, session.getClientID(), session.getPlatform(), sessionstatus, session.getLastActiveTime(), session.getAppName()));
|
||||
userOnlineStatus.sessions.add(new OutputCheckUserOnline.Session(userId, session.getClientID(), session.getPlatform(), sessionstatus, session.getLastActiveTime(), session.getAppName(), session.getIp()));
|
||||
}
|
||||
|
||||
HttpUtils.httpJsonPost(mUserOnlineStatusCallback, GsonUtil.gson.toJson(userOnlineStatus), HttpUtils.HttpPostType.POST_TYPE_User_Online_Event_Callback);
|
||||
|
||||
@@ -141,7 +141,7 @@ public class Qos1PublishHandler extends QosPublishHandler {
|
||||
status = 0;
|
||||
}
|
||||
|
||||
out.addSession(userId, session.getClientID(), session.getPlatform(), status, session.getLastActiveTime(), session.getAppName());
|
||||
out.addSession(userId, session.getClientID(), session.getPlatform(), status, session.getLastActiveTime(), session.getAppName(), session.getIp());
|
||||
}
|
||||
|
||||
callback.onRouteHandled(GsonUtil.gson.toJson(out).getBytes());
|
||||
|
||||
-6
@@ -3,18 +3,12 @@ package io.moquette.spi.impl.security;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.DESKeySpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
@@ -12,6 +12,7 @@ import io.moquette.server.Server;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
|
||||
public class GitRepositoryState {
|
||||
public final String tags;
|
||||
@@ -28,6 +29,8 @@ public class GitRepositoryState {
|
||||
public final String commitMessageFull;
|
||||
public final String commitMessageShort;
|
||||
public final String commitTime;
|
||||
public static final String globalLabel = UUID.randomUUID().toString();
|
||||
public String label;
|
||||
public final String closestTagName;
|
||||
public final String closestTagCommitCount;
|
||||
|
||||
@@ -63,6 +66,7 @@ public class GitRepositoryState {
|
||||
this.buildHost = String.valueOf(properties.get("git.build.host"));
|
||||
this.buildVersion = String.valueOf(properties.get("git.build.version"));
|
||||
this.runTime = Server.getServer().getRunTime();
|
||||
this.label = globalLabel;
|
||||
}
|
||||
|
||||
public static GitRepositoryState getGitRepositoryState() throws IOException {
|
||||
|
||||
@@ -10,6 +10,7 @@ package win.liyufan.im;
|
||||
|
||||
public interface IMTopic {
|
||||
String SendMessageTopic = "MS";
|
||||
String RobotReplyMessageTopic = "RRM";
|
||||
String MultiCastMessageTopic = "MMC";
|
||||
String RecallMessageTopic = "MR";
|
||||
String RecallMultiCastMessageTopic = "MRMC";
|
||||
@@ -51,6 +52,7 @@ public interface IMTopic {
|
||||
String FriendRequestPullTopic = "FRP";
|
||||
String NotifyFriendRequestTopic = "FRN";
|
||||
String RriendRequestUnreadSyncTopic = "FRUS";
|
||||
String SetFriendExtraTopic = "FES";
|
||||
|
||||
String DeleteFriendTopic = "FDL";
|
||||
String FriendPullTopic = "FP";
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
package win.liyufan.im;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class SensitiveFilter {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SensitiveFilter.class);
|
||||
public enum MatchType {
|
||||
MIN_MATCH("最小匹配规则"),MAX_MATCH("最大匹配规则");
|
||||
|
||||
@@ -71,6 +75,9 @@ public class SensitiveFilter {
|
||||
i=i+sensitiveWordLength-1;
|
||||
}
|
||||
}
|
||||
if(!sensitiveWords.isEmpty()) {
|
||||
LOG.info("Text {} matched sensitive word {}", originalText, sensitiveWords);
|
||||
}
|
||||
return sensitiveWords;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,4 +21,6 @@ public interface UserSettingScope {
|
||||
int kUserSettingGroupRemark = 26;
|
||||
int kUserSettingPrivacySearchable = 27;
|
||||
int kUserSettingAddFriendStrategy = 28;
|
||||
int kUserSettingScopeSyncBadge = 29;
|
||||
int UserSettingScopeLockPC = 30;
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>wildfirechat-parent</artifactId>
|
||||
<groupId>cn.wildfirechat</groupId>
|
||||
<version>1.3.3</version>
|
||||
<version>1.4.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
package cn.wildfirechat.common;
|
||||
|
||||
/**
|
||||
* API路径接口
|
||||
* <p>
|
||||
* 定义了野火IM服务器所有管理接口的API路径。
|
||||
* 包括聊天室、敏感词、域、用户、好友、黑名单、消息、群组、会议、频道等模块的接口路径。
|
||||
* </p>
|
||||
*/
|
||||
public interface APIPath {
|
||||
String Create_Chatroom = "/admin/chatroom/create";
|
||||
String Chatroom_Destroy = "/admin/chatroom/del";
|
||||
@@ -21,6 +28,7 @@ public interface APIPath {
|
||||
String Get_Domain = "/admin/domain/get";
|
||||
String Destroy_Domain = "/admin/domain/destroy";
|
||||
String List_Domain = "/admin/domain/list";
|
||||
String Ping_Domain = "/admin/domain/ping";
|
||||
|
||||
String Create_User = "/admin/user/create";
|
||||
String Update_User = "/admin/user/update";
|
||||
@@ -35,8 +43,11 @@ public interface APIPath {
|
||||
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_By_Mobile = "/admin/user/get_info_by_mobile";
|
||||
String User_Get_All = "/admin/user/all";
|
||||
String User_Get_Robot_Info = "/admin/user/get_robot_info";
|
||||
String User_Get_All_Robots = "/admin/user/get_all_robots";
|
||||
String User_Get_User_Robots = "/admin/user/get_user_robots";
|
||||
String User_Get_Blocked_List = "/admin/user/get_blocked_list";
|
||||
String User_Check_Block_Status = "/admin/user/check_block_status";
|
||||
String User_Get_Online_Status = "/admin/user/onlinestatus";
|
||||
@@ -61,6 +72,8 @@ public interface APIPath {
|
||||
|
||||
String Handle_Friend_Send_Request = "/admin/friend/handle_send_request";
|
||||
|
||||
String Admin_Moments_Post_Feed = "/admin/moments/feed/post";
|
||||
|
||||
String Msg_Send = "/admin/message/send";
|
||||
String Msg_Publish = "/admin/message/publish";
|
||||
String Msg_Recall = "/admin/message/recall";
|
||||
@@ -77,6 +90,7 @@ public interface APIPath {
|
||||
String Msg_Delivery = "/admin/message/delivery";
|
||||
String Conversation_Delete = "/admin/conversation/delete";
|
||||
String Msg_Clear_By_User = "/admin/message/clear_by_user";
|
||||
String Msg_Import = "/admin/message/import";
|
||||
|
||||
String Create_Group = "/admin/group/create";
|
||||
String Group_Dismiss = "/admin/group/del";
|
||||
@@ -92,6 +106,7 @@ public interface APIPath {
|
||||
String Group_Set_Manager = "/admin/group/manager/set";
|
||||
String Group_Mute_Member = "/admin/group/manager/mute";
|
||||
String Group_Allow_Member = "/admin/group/manager/allow";
|
||||
String Group_Join_Request_Add = "/admin/group/join_request/add";
|
||||
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";
|
||||
@@ -111,6 +126,11 @@ public interface APIPath {
|
||||
String Put_System_Setting = "/admin/system/put_setting";
|
||||
String GET_CUSTOMER = "/admin/customer";
|
||||
String Health = "/admin/health";
|
||||
String Get_Conversation_Files = "/admin/file/conversation_files";
|
||||
String Get_User_Files = "/admin/file/user_files";
|
||||
String Get_Message_File = "/admin/file/message_file";
|
||||
|
||||
String Get_Presigned_Upload_Url = "/admin/oss/get_upload_url";
|
||||
|
||||
String Conference_List = "/admin/conference/list";
|
||||
String Conference_Exist = "/admin/conference/exist";
|
||||
@@ -126,14 +146,19 @@ public interface APIPath {
|
||||
String Channel_Update_Profile = "/channel/update_profile";
|
||||
String Channel_Get_Profile = "/channel/get_profile";
|
||||
String Channel_Message_Send = "/channel/message/send";
|
||||
String Channel_Msg_Recall = "/channel/message/recall";
|
||||
String Channel_Msg_Republish = "/channel/message/republish";
|
||||
String Channel_Subscribe = "/channel/subscribe";
|
||||
String Channel_Subscriber_List = "/channel/subscriber_list";
|
||||
String Channel_Is_Subscriber = "/channel/is_subscriber";
|
||||
String Channel_Application_Get_UserInfo = "/channel/application/get_user_info";
|
||||
|
||||
String Robot_User_Info = "/robot/user_info";
|
||||
String Robot_User_Get_Email_Info = "/robot/user/get_info_by_email";
|
||||
String Robot_User_Batch_Get_Infos = "/robot/user/batch_get_infos";
|
||||
String Robot_Get_Profile = "/robot/profile";
|
||||
String Robot_Message_Send = "/robot/message/send";
|
||||
String Robot_Message_Reply = "/robot/message/reply";
|
||||
String Robot_Message_Recall = "/robot/message/recall";
|
||||
String Robot_Message_Update = "/robot/message/update";
|
||||
String Robot_Set_Callback = "/robot/set_callback";
|
||||
@@ -170,4 +195,6 @@ public interface APIPath {
|
||||
String Robot_Moments_Update_Profiles_Value = "/robot/moments/profiles/value/push";
|
||||
|
||||
String Robot_Conference_Request = "/robot/conference/request";
|
||||
|
||||
String Robot_Get_Presigned_Upload_Url = "/robot/oss/get_upload_url";
|
||||
}
|
||||
|
||||
@@ -8,6 +8,25 @@
|
||||
|
||||
package cn.wildfirechat.common;
|
||||
|
||||
/**
|
||||
* 错误码枚举
|
||||
* <p>
|
||||
* 定义了野火IM系统中所有可能的错误码,包括:
|
||||
* <ul>
|
||||
* <li>通用错误(0-5)</li>
|
||||
* <li>认证错误(6-8)</li>
|
||||
* <li>消息错误(9-10)</li>
|
||||
* <li>群组错误(11-12)</li>
|
||||
* <li>用户错误(16-19)</li>
|
||||
* <li>聊天室错误(20)</li>
|
||||
* <li>频道错误(21-25)</li>
|
||||
* <li>会议错误(60-61)</li>
|
||||
* <li>应用错误(70)</li>
|
||||
* <li>密聊错误(81-87)</li>
|
||||
* <li>其他错误(90-255)</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public enum ErrorCode {
|
||||
//General error
|
||||
ERROR_CODE_SUCCESS(0, "success"),
|
||||
@@ -49,6 +68,7 @@ public enum ErrorCode {
|
||||
ERROR_CODE_ROBOT_NO_TOKEN(27, "robot no token"),
|
||||
ERROR_CODE_WS_NOT_CONFIGURED_CORRECTLY(28, "ws not configured correctly"),
|
||||
ERROR_CODE_TIME_INCONSISTENT(30, "time inconsistent"),
|
||||
ERROR_CODE_MESSAGE_TOO_LARGE(35, "message too large"),
|
||||
ERROR_CODE_CONFERENCE_ROOM_NOT_EXIST(60, "conference room not exist"),
|
||||
ERROR_CODE_CONFERENCE_SERVICE_NOT_AVAILABLE(61, "conference service not available"),
|
||||
|
||||
@@ -65,6 +85,8 @@ public enum ErrorCode {
|
||||
ERROR_CODE_CONFERENCE_ERROR(90, "Conference server response error"),
|
||||
|
||||
ERROR_CODE_FUNCTION_DISABLED(220, "function disabled"),
|
||||
ERROR_CODE_SERVER_BUSY(221, "Server busy"),
|
||||
ERROR_CODE_PARTLY_SUCCESS(222, "Partly success"),
|
||||
|
||||
ERROR_CODE_OTHER_CLIENT_ALREADY_IN_CHATROOM(225, "other client already in chatroom"),
|
||||
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
package cn.wildfirechat.common;
|
||||
|
||||
/**
|
||||
* IM异常事件类
|
||||
* <p>
|
||||
* 用于记录和传递IM系统中的异常事件信息。
|
||||
* </p>
|
||||
*/
|
||||
public class IMExceptionEvent {
|
||||
/**
|
||||
* 事件类型接口
|
||||
* <p>
|
||||
* 定义了各种异常事件的类型常量。
|
||||
* </p>
|
||||
*/
|
||||
public interface EventType {
|
||||
int RDBS_Exception = 1;
|
||||
int MONGO_Exception = 2;
|
||||
|
||||
@@ -8,6 +8,13 @@
|
||||
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
/**
|
||||
* 会话类
|
||||
* <p>
|
||||
* 表示一个会话对象,包含会话类型、目标ID和线路信息。
|
||||
* 用于标识消息发送或接收的目标会话。
|
||||
* </p>
|
||||
*/
|
||||
public class Conversation {
|
||||
private int type;
|
||||
private String target;
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FilesPojo {
|
||||
public int total;
|
||||
public List<FilePojo> files;
|
||||
public static class FilePojo {
|
||||
public long messageId;
|
||||
public String sender;
|
||||
public int conversationType;
|
||||
public String target;
|
||||
public int line;
|
||||
public String name;
|
||||
public String url;
|
||||
public int size;
|
||||
public int downloadCount;
|
||||
public long timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
public class GetConversationFilesPojo {
|
||||
public int conversationType;
|
||||
public String target;
|
||||
public int line;
|
||||
public String userId;
|
||||
public int offset;
|
||||
public boolean desc;
|
||||
public int count;
|
||||
}
|
||||
@@ -7,6 +7,7 @@ public class GetOnlineUserResult {
|
||||
public String userId;
|
||||
public String clientId;
|
||||
public int platform;
|
||||
public String ip;
|
||||
}
|
||||
|
||||
public ArrayList<GetOnlineUserResult.UserClient> userClients;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
public class GetUserFilesPojo {
|
||||
public String userId;
|
||||
public int offset;
|
||||
public boolean desc;
|
||||
public int count;
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import com.google.protobuf.ByteString;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class GroupNotificationBinaryContent {
|
||||
//groupId
|
||||
@@ -33,6 +34,8 @@ public class GroupNotificationBinaryContent {
|
||||
//value2(member or something)
|
||||
private String m;
|
||||
|
||||
private Map<String, Integer> mi;
|
||||
|
||||
private String extra;
|
||||
|
||||
public GroupNotificationBinaryContent() {
|
||||
@@ -92,6 +95,11 @@ public class GroupNotificationBinaryContent {
|
||||
this.ms = ms;
|
||||
}
|
||||
|
||||
public GroupNotificationBinaryContent setMi(Map<String, Integer> mi) {
|
||||
this.mi = mi;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GroupNotificationBinaryContent setExtra(String extra) {
|
||||
this.extra = extra;
|
||||
return this;
|
||||
|
||||
@@ -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 cn.wildfirechat.proto.WFCMessage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ImportMessagesData {
|
||||
public static class ImportMessage {
|
||||
public String sender;
|
||||
public Conversation conversation;
|
||||
public MessagePayload payload;
|
||||
public List<String> receivers;
|
||||
public long timestamp;
|
||||
}
|
||||
public List<ImportMessage> messages;
|
||||
}
|
||||
@@ -14,6 +14,12 @@ import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 添加群组成员输入参数类
|
||||
* <p>
|
||||
* 封装添加群组成员的输入参数,包括群组ID、成员列表、成员额外信息等。
|
||||
* </p>
|
||||
*/
|
||||
public class InputAddGroupMember extends InputGroupBase {
|
||||
private String group_id;
|
||||
private List<PojoGroupMember> members;
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
public class InputCountOffset {
|
||||
public int count;
|
||||
public int offset;
|
||||
}
|
||||
@@ -12,6 +12,9 @@ package cn.wildfirechat.pojos;
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class InputCreateChannel {
|
||||
private String owner;
|
||||
private String name;
|
||||
@@ -24,6 +27,7 @@ public class InputCreateChannel {
|
||||
private int state;
|
||||
private String extra;
|
||||
private long updateDt;
|
||||
public List<PojoChannelMenu> menus;
|
||||
|
||||
public WFCMessage.ChannelInfo toProtoChannelInfo() {
|
||||
WFCMessage.ChannelInfo.Builder builder = WFCMessage.ChannelInfo.newBuilder().setOwner(owner);
|
||||
@@ -48,6 +52,12 @@ public class InputCreateChannel {
|
||||
else
|
||||
builder = builder.setUpdateDt(System.currentTimeMillis());
|
||||
|
||||
if (menus != null && !menus.isEmpty()) {
|
||||
for (PojoChannelMenu menu : menus) {
|
||||
builder.addMenu(menu.toPbInfo());
|
||||
}
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,12 @@ import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 创建群组输入参数类
|
||||
* <p>
|
||||
* 封装创建群组的输入参数,包括群组信息、成员列表、成员额外信息等。
|
||||
* </p>
|
||||
*/
|
||||
public class InputCreateGroup extends InputGroupBase {
|
||||
private PojoGroup group;
|
||||
private String member_extra;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
|
||||
/**
|
||||
* 请求预签名上传地址
|
||||
* <p>
|
||||
* 请求封装预签名上传地址,包括:
|
||||
* <ul>
|
||||
* <li>文件名</li>
|
||||
* <li>文件类型</li>
|
||||
* <li>媒体类型</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public class InputGetPresignedUploadUrl {
|
||||
public String fileName;
|
||||
public String contentType;
|
||||
public int mediaType;
|
||||
}
|
||||
@@ -12,6 +12,7 @@ public class InputGetUserInfo {
|
||||
private String userId;
|
||||
private String name;
|
||||
private String mobile;
|
||||
private boolean includeDeleted;
|
||||
|
||||
public InputGetUserInfo() {
|
||||
}
|
||||
@@ -22,6 +23,13 @@ public class InputGetUserInfo {
|
||||
this.mobile = mobile;
|
||||
}
|
||||
|
||||
public InputGetUserInfo(String userId, String name, String mobile, boolean includeDeleted) {
|
||||
this.userId = userId;
|
||||
this.name = name;
|
||||
this.mobile = mobile;
|
||||
this.includeDeleted = includeDeleted;
|
||||
}
|
||||
|
||||
public String getMobile() {
|
||||
return mobile;
|
||||
}
|
||||
@@ -45,4 +53,12 @@ public class InputGetUserInfo {
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean isIncludeDeleted() {
|
||||
return includeDeleted;
|
||||
}
|
||||
|
||||
public void setIncludeDeleted(boolean includeDeleted) {
|
||||
this.includeDeleted = includeDeleted;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,21 @@ package cn.wildfirechat.pojos;
|
||||
|
||||
import cn.wildfirechat.proto.WFCMessage;
|
||||
|
||||
/**
|
||||
* 用户信息类
|
||||
* <p>
|
||||
* 封装用户的所有信息,包括:
|
||||
* <ul>
|
||||
* <li>用户ID、用户名、显示名称</li>
|
||||
* <li>头像、性别</li>
|
||||
* <li>手机号、邮箱、地址</li>
|
||||
* <li>公司、社交信息</li>
|
||||
* <li>用户类型、删除状态</li>
|
||||
* <li>更新时间</li>
|
||||
* <li>额外扩展信息</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public class InputOutputUserInfo {
|
||||
private String userId;
|
||||
private String name;
|
||||
@@ -25,6 +40,7 @@ public class InputOutputUserInfo {
|
||||
private String social;
|
||||
private String extra;
|
||||
private int type;
|
||||
private int deleted;
|
||||
private long updateDt;
|
||||
|
||||
public static InputOutputUserInfo fromPbUser(WFCMessage.User pbUser) {
|
||||
@@ -42,6 +58,7 @@ public class InputOutputUserInfo {
|
||||
inputCreateUser.extra = pbUser.getExtra();
|
||||
inputCreateUser.type = pbUser.getType();
|
||||
inputCreateUser.updateDt = pbUser.getUpdateDt();
|
||||
inputCreateUser.deleted = pbUser.getDeleted();
|
||||
return inputCreateUser;
|
||||
}
|
||||
|
||||
@@ -77,6 +94,7 @@ public class InputOutputUserInfo {
|
||||
newUserBuilder.setExtra(getExtra());
|
||||
newUserBuilder.setGender(gender);
|
||||
newUserBuilder.setType(type);
|
||||
newUserBuilder.setDeleted(deleted);
|
||||
|
||||
newUserBuilder.setUpdateDt(System.currentTimeMillis());
|
||||
return newUserBuilder.build();
|
||||
@@ -185,4 +203,24 @@ public class InputOutputUserInfo {
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public int getDeleted() {
|
||||
return deleted;
|
||||
}
|
||||
|
||||
public void setDeleted(int deleted) {
|
||||
this.deleted = deleted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" +
|
||||
"userId='" + userId + '\'' +
|
||||
", name='" + name + '\'' +
|
||||
", displayName='" + displayName + '\'' +
|
||||
", portrait='" + portrait + '\'' +
|
||||
", mobile='" + mobile + '\'' +
|
||||
", updateDt=" + updateDt +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package cn.wildfirechat.pojos;
|
||||
|
||||
public class LongPojo {
|
||||
public long value;
|
||||
}
|
||||
@@ -16,6 +16,22 @@ import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 消息内容负载类
|
||||
* <p>
|
||||
* 封装消息的所有内容信息,包括:
|
||||
* <ul>
|
||||
* <li>消息类型</li>
|
||||
* <li>可搜索内容(文本消息的文本)</li>
|
||||
* <li>推送内容和推送数据</li>
|
||||
* <li>消息内容(二进制数据)</li>
|
||||
* <li>媒体类型和远程URL</li>
|
||||
* <li>持久化标志和过期时间</li>
|
||||
* <li>@提及信息</li>
|
||||
* <li>额外数据</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public class MessagePayload {
|
||||
private int type;
|
||||
private String searchableContent;
|
||||
|
||||
@@ -20,22 +20,24 @@ public class OutputCheckUserOnline {
|
||||
public int status; //0 online, 1 have session offline
|
||||
public long lastSeen;
|
||||
public String packageName;
|
||||
public String ip;
|
||||
|
||||
public Session() {
|
||||
}
|
||||
|
||||
public Session(String clientId, String userId, int platform, int status, long lastSeen, String packageName) {
|
||||
public Session(String clientId, String userId, int platform, int status, long lastSeen, String packageName, String ip) {
|
||||
this.clientId = clientId;
|
||||
this.userId = userId;
|
||||
this.platform = platform;
|
||||
this.status = status;
|
||||
this.lastSeen = lastSeen;
|
||||
this.packageName = packageName;
|
||||
this.ip = ip;
|
||||
}
|
||||
}
|
||||
|
||||
public void addSession(String userId, String clientId, int platform, int status, long lastSeen, String packageName) {
|
||||
Session session = new Session(clientId, userId, platform, status, lastSeen, packageName);
|
||||
public void addSession(String userId, String clientId, int platform, int status, long lastSeen, String packageName, String ip) {
|
||||
Session session = new Session(clientId, userId, platform, status, lastSeen, packageName, ip);
|
||||
sessions.add(session);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,9 +13,11 @@ import cn.wildfirechat.proto.WFCMessage;
|
||||
|
||||
public class OutputCreateChannel {
|
||||
private String targetId;
|
||||
private String secret;
|
||||
|
||||
public OutputCreateChannel(String targetId) {
|
||||
public OutputCreateChannel(String targetId, String secret) {
|
||||
this.targetId = targetId;
|
||||
this.secret = secret;
|
||||
}
|
||||
|
||||
public String getTargetId() {
|
||||
@@ -25,4 +27,12 @@ public class OutputCreateChannel {
|
||||
public void setTargetId(String targetId) {
|
||||
this.targetId = targetId;
|
||||
}
|
||||
|
||||
public String getSecret() {
|
||||
return secret;
|
||||
}
|
||||
|
||||
public void setSecret(String secret) {
|
||||
this.secret = secret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,61 +16,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class OutputGetChannelInfo {
|
||||
public static class OutputMenu {
|
||||
public String menuId;
|
||||
public String type;
|
||||
public String name;
|
||||
public String key;
|
||||
public String url;
|
||||
public String mediaId;
|
||||
public String articleId;
|
||||
public String appId;
|
||||
public String appPage;
|
||||
public String extra;
|
||||
public List<OutputMenu> subMenus;
|
||||
|
||||
public static OutputMenu fromPbInfo(WFCMessage.ChannelMenu channelMenuMenu) {
|
||||
OutputMenu out = new OutputMenu();
|
||||
out.menuId = channelMenuMenu.getMenuId();
|
||||
out.type = channelMenuMenu.getType();
|
||||
out.name = channelMenuMenu.getName();
|
||||
out.key = channelMenuMenu.getKey();
|
||||
out.url = channelMenuMenu.getUrl();
|
||||
out.mediaId = channelMenuMenu.getMediaId();
|
||||
out.articleId = channelMenuMenu.getArticleId();
|
||||
out.appId = channelMenuMenu.getAppId();
|
||||
out.appPage = channelMenuMenu.getAppPage();
|
||||
out.extra = channelMenuMenu.getExtra();
|
||||
if (channelMenuMenu.getSubMenuCount() > 0) {
|
||||
out.subMenus = new ArrayList<>();
|
||||
for (WFCMessage.ChannelMenu menuMenu : channelMenuMenu.getSubMenuList()) {
|
||||
out.subMenus.add(fromPbInfo(menuMenu));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
public WFCMessage.ChannelMenu.Builder toPbInfo() {
|
||||
WFCMessage.ChannelMenu.Builder builder = WFCMessage.ChannelMenu.newBuilder();
|
||||
builder.setType(type);
|
||||
builder.setName(name);
|
||||
if (!StringUtil.isNullOrEmpty(menuId)) builder.setMenuId(menuId);
|
||||
if (!StringUtil.isNullOrEmpty(key)) builder.setKey(key);
|
||||
if (!StringUtil.isNullOrEmpty(url)) builder.setUrl(url);
|
||||
if (!StringUtil.isNullOrEmpty(mediaId)) builder.setMediaId(mediaId);
|
||||
if (!StringUtil.isNullOrEmpty(articleId)) builder.setArticleId(articleId);
|
||||
if (!StringUtil.isNullOrEmpty(appId)) builder.setAppId(appId);
|
||||
if (!StringUtil.isNullOrEmpty(appPage)) builder.setAppPage(appPage);
|
||||
if (!StringUtil.isNullOrEmpty(extra)) builder.setExtra(extra);
|
||||
if (subMenus != null && !subMenus.isEmpty()) {
|
||||
subMenus.forEach(menuMenu -> builder.addSubMenu(menuMenu.toPbInfo()));
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
public static class OutputMenuList extends ArrayList<OutputMenu> {
|
||||
|
||||
public static class OutputMenuList extends ArrayList<PojoChannelMenu> {
|
||||
}
|
||||
|
||||
private String channelId;
|
||||
@@ -85,7 +31,7 @@ public class OutputGetChannelInfo {
|
||||
private String callback;
|
||||
private int automatic;
|
||||
private String secret;
|
||||
public List<OutputMenu> menus;
|
||||
public List<PojoChannelMenu> menus;
|
||||
|
||||
public String getChannelId() {
|
||||
return channelId;
|
||||
@@ -200,7 +146,7 @@ public class OutputGetChannelInfo {
|
||||
if (channelInfo.getMenuCount() > 0) {
|
||||
out.menus = new ArrayList<>();
|
||||
for (WFCMessage.ChannelMenu channelMenuMenu : channelInfo.getMenuList()) {
|
||||
out.menus.add(OutputMenu.fromPbInfo(channelMenuMenu));
|
||||
out.menus.add(PojoChannelMenu.fromPbInfo(channelMenuMenu));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user