Compare commits

...
71 Commits
Author SHA1 Message Date
heavyrian2012 f672f4550e update version and release note 2022-08-31 20:30:03 +08:00
heavyrian2012 04c89d1fc1 gson单例化,另外关掉gson html转义功能 2022-08-31 20:24:46 +08:00
heavyrian2012 97540bdd1b IM exception add node_id 2022-08-26 23:13:04 +08:00
heavyrain2012 8514d808b3 remove useless file 2022-08-26 19:31:57 +08:00
heavyrain2012 e8e3d91dbc update 2022-08-26 19:18:16 +08:00
heavyrain2012 b64316c67d 添加超频限制白名单,某些命令不受超频限制 2022-08-26 19:11:52 +08:00
heavyrian2012 650ffa14e2 添加检查是否订阅频道server api 2022-08-26 15:16:48 +08:00
heavyrian2012 9fa33159c8 解决内置存储某些类型文件返回content-type错误问题 2022-08-26 00:22:18 +08:00
heavyrian2012 35794a777b sdk添加删除会话接口 2022-08-26 00:19:57 +08:00
heavyrian2012 bf60ed2d7d Merge branch 'wildfirechat' of github.com:wildfirechat/im-server into wildfirechat 2022-08-25 21:02:55 +08:00
heavyrian2012 0d09aad24f update readme 2022-08-25 21:02:40 +08:00
heavyrain2012 8d31e031bc update version and release 2022-08-25 14:22:58 +08:00
heavyrian2012 9af2bbf3d0 添加敏感词命中回调 2022-08-23 14:17:31 +08:00
heavyrian2012 d391ba386c http client 添加部分参数,解决调用server sdk时可能出现的connection reset问题 2022-08-23 14:11:34 +08:00
heavyrian2012 b2ef3152db 短链接添加head处理 2022-08-22 15:28:24 +08:00
heavyrian2012 05fe5bd766 server api添加订阅接口 2022-08-20 13:43:12 +08:00
heavyrian2012 48c9b10365 添加release note 2022-08-19 08:50:45 +08:00
heavyrian2012 30cd56aae2 version 0.92 2022-08-19 08:23:19 +08:00
heavyrian2012 6fbecfb0fb 去掉无效的警告 2022-08-19 08:15:03 +08:00
heavyrian2012 d2cb8427bb 解决下载zip包编译失败的问题 2022-08-19 08:05:54 +08:00
heavyrian2012 826bad2d66 add menuid and extra 2022-08-16 20:10:56 +08:00
heavyrian2012 aaccec00e9 add article content 2022-08-16 15:05:30 +08:00
heavyrian2012 3c1c5ce6d3 menu 2022-08-14 22:08:35 +08:00
heavyrian2012 b0fe1636a7 添加配置,在关闭消息漫游时,客户端首次登陆同步多久时间以内的消息 2022-08-14 15:25:00 +08:00
heavyrian2012 014cd3844d 频道只有auto为1时才会回调消息和订阅事件。频道只回调用户发送的消息,自己发送的消息不回调 2022-08-09 15:39:34 +08:00
heavyrian2012 6cc00950f0 SDK部分pojo对象添加无参数构造函数 2022-08-09 12:17:59 +08:00
heavyrian2012 2918c06a01 version 0.91 2022-08-03 12:41:35 +08:00
heavyrian2012 c3b9b9fccf 群组添加成员时,检查是否已经存在群组成员, fix issue #501 2022-08-03 12:19:03 +08:00
heavyrian2012 8c88d5a13f 添加注释 2022-07-29 20:37:53 +08:00
heavyrian2012 967526f5ec 添加发送消息payload错误时的提醒 2022-07-29 20:33:18 +08:00
heavyrian2012 109078abca 参数有效性检查 2022-07-29 20:24:41 +08:00
heavyrian2012 79a58e99aa 添加配置运行回调消息带上客户端信息 2022-07-27 11:36:04 +08:00
heavyrian2012 a394444c86 创建群组时,检查群组类型的有效性 2022-07-21 22:10:39 +08:00
heavyrian2012 dece1d7a1c sdk 添加获取会话阅读时间和消息送达时间接口 2022-07-20 22:25:46 +08:00
heavyrian2012 2b09a7bf84 version 0.90 2022-07-14 20:25:52 +08:00
heavyrian2012 200a6ebd04 添加注释 2022-07-14 20:22:36 +08:00
heavyrian2012 54db1f3b06 触发限频后多调用了一次callback,去掉无用的调用 2022-07-06 10:05:57 +08:00
heavyrian2012 3b90d145a4 去掉绑定IP地址的配置,防止客户误操作 2022-06-28 08:34:17 +08:00
heavyrain.lee e16a116fe4 Merge pull request #487 from wildfirechat/dependabot/maven/broker/mysql-mysql-connector-java-8.0.28
Bump mysql-connector-java from 8.0.19 to 8.0.28 in /broker
2022-06-26 18:34:33 +08:00
dependabot[bot] 7bd0937069 Bump mysql-connector-java from 8.0.19 to 8.0.28 in /broker
Bumps [mysql-connector-java](https://github.com/mysql/mysql-connector-j) from 8.0.19 to 8.0.28.
- [Release notes](https://github.com/mysql/mysql-connector-j/releases)
- [Changelog](https://github.com/mysql/mysql-connector-j/blob/release/8.0/CHANGES)
- [Commits](https://github.com/mysql/mysql-connector-j/compare/8.0.19...8.0.28)

---
updated-dependencies:
- dependency-name: mysql:mysql-connector-java
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-06-21 00:59:19 +00:00
heavyrian2012 c085057032 修正拼写错误 2022-06-09 15:03:56 +08:00
heavyrian2012 eac6648fc0 version 0.89 2022-06-09 09:42:34 +08:00
heavyrian2012 300f9aa0e6 update readme 2022-06-07 21:12:33 +08:00
heavyrian2012 dd40b72ec4 添加允许pc多端的配置 2022-06-06 09:37:37 +08:00
heavyrian2012 556e6ad2a0 解决某些java版本下反序列化IMResult<Void>失败问题 2022-05-27 13:25:21 +08:00
heavyrian2012 473ae32f57 update readme 2022-05-27 10:14:00 +08:00
heavyrian2012 d57ae2ed58 删除群组时清除相关设置 2022-05-27 08:35:12 +08:00
heavyrian2012 1a6907efd3 log4j version 2.17.2 2022-05-25 10:16:40 +08:00
heavyrain.lee 1624c470d6 Merge pull request #480 from wildfirechat/dependabot/maven/common/com.google.code.gson-gson-2.8.9
Bump gson from 2.8.2 to 2.8.9 in /common
2022-05-25 10:10:17 +08:00
heavyrain.lee 5ea6eefe67 Merge pull request #481 from wildfirechat/dependabot/maven/sdk/com.google.code.gson-gson-2.8.9
Bump gson from 2.8.2 to 2.8.9 in /sdk
2022-05-25 10:10:02 +08:00
heavyrian2012 8aebb2537a version 0.88 2022-05-23 14:53:40 +08:00
heavyrian2012 250b0ccebe 解决server api撤回单聊消息无法撤回的问题 2022-05-23 14:20:30 +08:00
heavyrian2012 91669c634f add send articles message builder 2022-05-22 11:26:01 +08:00
dependabot[bot] bf51cb9829 Bump gson from 2.8.2 to 2.8.9 in /sdk
Bumps [gson](https://github.com/google/gson) from 2.8.2 to 2.8.9.
- [Release notes](https://github.com/google/gson/releases)
- [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/gson/compare/gson-parent-2.8.2...gson-parent-2.8.9)

---
updated-dependencies:
- dependency-name: com.google.code.gson:gson
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-05-20 21:09:22 +00:00
dependabot[bot] baadcac2c6 Bump gson from 2.8.2 to 2.8.9 in /common
Bumps [gson](https://github.com/google/gson) from 2.8.2 to 2.8.9.
- [Release notes](https://github.com/google/gson/releases)
- [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/gson/compare/gson-parent-2.8.2...gson-parent-2.8.9)

---
updated-dependencies:
- dependency-name: com.google.code.gson:gson
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2022-05-20 21:09:06 +00:00
heavyrian2012 6c69a5ac96 null 判断 2022-05-19 12:37:01 +08:00
heavyrian2012 eb19ed3301 添加富通知消息的发送测试 2022-05-19 10:29:24 +08:00
heavyrian2012 5be7576bb8 管理端口获取authCode时使用默认的applicationId 2022-05-15 17:16:37 +08:00
heavyrian2012 86d552cd82 管理端口也添加获取应用authCode的方法 2022-05-15 15:07:51 +08:00
heavyrian2012 391f7345c0 add authcode and config api for open platform 2022-05-15 10:19:07 +08:00
heavyrian2012 92fa40f1fd 添加server api和机器人api获取机器人信息的接口 2022-05-13 14:38:26 +08:00
heavyrian2012 3b3c05260c 频道automic状态为1所有消息都不发送到owner,无论callback是否存在 2022-05-12 08:47:26 +08:00
heavyrian2012 4e9cf86302 机器人和频道回调消息带上messageid和时间戳 2022-05-11 09:28:06 +08:00
heavyrian2012 cbb89bbfb5 解决删除用户时,没有回调取消订阅通知的问题 2022-05-07 09:16:15 +08:00
heavyrian2012 537221b0b4 add application token 2022-05-02 22:07:54 +08:00
heavyrian2012 9d23f9c996 优化频道订阅关系缓存逻辑 2022-05-02 11:12:19 +08:00
heavyrian2012 6a25a83857 删除用户或删除频道时,删除对于的订阅关系 2022-05-02 11:05:56 +08:00
heavyrian2012 d0e533ad21 channel add member index 2022-05-02 10:57:46 +08:00
heavyrian2012 cd0e07f32d 优化sql语句 2022-05-01 12:14:07 +08:00
heavyrian2012 a6869c9072 消息表添加会话索引 2022-04-30 21:30:06 +08:00
heavyrian2012 03b3bb2093 同步专业版数据库及错误码 2022-04-30 08:01:45 +08:00
123 changed files with 8382 additions and 575 deletions
+10 -3
View File
@@ -2,7 +2,7 @@
野火IM是专业级的即时通讯和实时音视频整体解决方案,由北京野火无限网络科技有限公司维护和支持。
## 功能特性
* 超低硬件配置要求,IM服务最低128M内存即可运行。
* 极致地硬件利用率,IM服务最低128M内存即可运行,上不封顶。
* 协议先进,采用MQTT+Protobuf组合,流量和性能极致优化。
* 性能强大,专业版IM服务支持百万在线和集群部署。
* 部署运维简单,依赖服务少,稍加配置一键启动。
@@ -16,13 +16,15 @@
* 高级音视频功能强大,支持9人以上的群组视频通话,支持1080P视频,支持会议模式,支持百人以上会议,支持服务器端录制。
* 全私有部署,可不依赖任何第三方服务,完全内网部署。
* 功能齐全,涵盖所有常见即时通讯功能。另外具有强大的可扩展能力。Demo成熟完善,基本可以做到开箱即用,也可把SDK嵌入其它应用。
* 拥有应用开放平台,可以开发和创建自建应用,扩展您的工作台。
* API丰富,方便与其它服务系统的对接。
* 拥有机器人和频道功能。
* 代码开源率高,二次开发简单。可以先试用3到6个月,二开搞定后再购买。
## 野火开源项目
主要包括一下项目:
主要包括以下项目:
| [GitHub仓库地址(主站)](https://github.com/wildfirechat) | [码云仓库地址(镜像)](https://gitee.com/wfchat) | 说明
| [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应用服务,模拟客户的应用服登陆处理逻辑及部分二次开发示例。 |
@@ -30,11 +32,16 @@
| [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服务。 |
| [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平台原生插件 |
| [flutter_imclient](https://github.com/wildfirechat/flutter_imclient) | [flutter_imclient](https://gitee.com/wfchat/flutter_imclient) | Flutter平台原生插件 |
| [docs](https://github.com/wildfirechat/docs) | [docs](https://gitee.com/wfchat/docs) | 野火IM相关文档,包含设计、概念、开发、使用说明,[在线查看](https://docs.wildfirechat.cn/) |
## 野火开发文档
+22 -3
View File
@@ -26,8 +26,8 @@ http.admin.port 18080
##节点ID,当集群部署时,一定不能有重复。
node_id 1
##绑定IP,保持不变即可
host 0.0.0.0
##绑定IP,不要打开,除非有特殊需求才可以打开
#host 0.0.0.0
##本地绑定端口
local_port 80
@@ -38,6 +38,7 @@ embed.db 1
## 是否自动清理历史消息记录,当为true时,IM服务会定时扫描t_messages_x和t_user_messages_x表,清除掉3年前的历史消息。
## 如果不开启自动清理,需要手动清理t_messages_x和t_user_messages_x表内的历史数据,保存数据不能超过3年。
## 如果需要消息保存更长时间,可以把临近销毁的消息转储到别的数据库,客户端在拉取不到服务器消息时,再去转储的数据库拉取。
## 使用mongodb时次开关无效(因为mongodb设置了消息过期时间,会自动清理,仅专业版支持mongodb)。
db.auto_clean_history_messages true
@@ -56,10 +57,13 @@ token.key testim
##token.expire_time 2592000000
##首次登录,是否接收之前的历史消息。
##0 不接收历史消息,只接收5分钟以内的消息,由于服务器没有保存已经收取记录,所以如果有超过5分钟之前未收取的消息也不会收取下拉;
##0 不接收历史消息,只接收${message.compensate_time_limit}毫秒以内的消息,由于服务器没有保存已经收取记录,所以如果有超过${message.compensate_time_limit}毫秒之前未收取的消息也不会收取下拉;
##1接收,会接收 message.max_queue 配置的条数的历史消息
message.roaming 0
## 消息补偿时限,当${message.roaming}为0时,会同步时限以内且小于${message.max_queue}的消息,默认时限为5分钟。当${message.roaming}为1时,会接收 message.max_queue 配置的条数的历史消息。
message.compensate_time_limit 300000
##是否开启拉取远程历史消息。如果为1,客户端在会话内如果本地消息读取完了,可以下拉继续加载在服务器上的该会话的消息;如果为0则不能。
message.remote_history_message 0
@@ -108,6 +112,14 @@ message.global_mute_exception_types 401,402,403,404,405,407,408,410,411
## 当为true时,不转发server api发送的消息;当为false时,转发server api发送的消息。
message.no_forward_admin_message false
## 消息转发功能开启时,转发信息是否带上用户clientId和平台类型。
message.forward_with_client_info false
## 机器人回调信息是否带上用户clientId和平台类型。
robot.callback_with_client_info false
## 频道回调信息是否带上用户clientId和平台类型。
channel.callback_with_client_info false
##禁止搜索用户
friend.disable_search false
@@ -238,6 +250,9 @@ local.media.storage.root media
# 建议使用false
server.multi_endpoint false
## 是否支持PC多端登陆,当server.multi_endpoint为true时,此开关无意义,当为false时,可以单独打开PC端多端登录。
server.multi_pc_endpoint false
# 多平台连接状态通知(仅当multi_endpoint为false时有效),true时移动端可以收到pc或web端登录的通知。
server.multi_platform_notification true
@@ -289,6 +304,10 @@ push.ios.server.address http://localhost:8085/ios/push
##需要转发的消息类型,当有多个时以英文逗号分割。如果转发所有消息,请注释掉配置或者设置为空
#message.forward.types 1,2,3
##敏感消息转发地址
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#message.sensitive.forward.url http://localhost:8888/im_event/message
##提醒消息转发地址,@全体用户和@某个用户消息会回调此地址。此转发不受${message.forward.types}限制。
##注意回调是单线程回调,接收服务必须在同一内网,且异步处理快速返回,否则会有延迟问题!!
#message.mentionmsg.forward.url http://localhost:8888/im_event/message
+13
View File
@@ -0,0 +1,13 @@
DROP TABLE IF EXISTS `t_secret_chat`;
CREATE TABLE `t_secret_chat` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`_uid` varchar(64) NOT NULL,
`_from` varchar(64) DEFAULT '',
`_from_cid` varchar(64) DEFAULT '',
`_to` varchar(64) DEFAULT '',
`_to_cid` varchar(64) DEFAULT '',
`_state` tinyint NOT NULL DEFAULT 0,
`_dt` bigint(20) NOT NULL,
UNIQUE INDEX `secret_chat_uid_index` (`_uid` DESC)
);
@@ -0,0 +1 @@
alter table `t_messages` add INDEX `messages_conv_index` ( `_type`, `_target`, `_line`);
@@ -0,0 +1 @@
alter table `t_channel_listener` add INDEX `channel_mid_index` ( `_mid`);
+1
View File
@@ -0,0 +1 @@
alter table `t_channel` add column `_menu` BLOB DEFAULT NULL;
+16
View File
@@ -0,0 +1,16 @@
DROP TABLE IF EXISTS `t_secret_chat`;
CREATE TABLE `t_secret_chat` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`_uid` varchar(64) NOT NULL,
`_from` varchar(64) DEFAULT '',
`_from_cid` varchar(64) DEFAULT '',
`_to` varchar(64) DEFAULT '',
`_to_cid` varchar(64) DEFAULT '',
`_state` tinyint NOT NULL DEFAULT 0,
`_dt` bigint(20) NOT NULL,
UNIQUE INDEX `secret_chat_uid_index` (`_uid` DESC)
)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_bin;
@@ -0,0 +1,37 @@
alter table `t_messages` add INDEX `messages_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_0` add INDEX `messages0_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_1` add INDEX `messages1_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_2` add INDEX `messages2_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_3` add INDEX `messages3_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_4` add INDEX `messages4_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_5` add INDEX `messages5_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_6` add INDEX `messages6_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_7` add INDEX `messages7_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_8` add INDEX `messages8_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_9` add INDEX `messages9_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_10` add INDEX `messages10_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_11` add INDEX `messages11_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_12` add INDEX `messages12_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_13` add INDEX `messages13_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_14` add INDEX `messages14_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_15` add INDEX `messages15_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_16` add INDEX `messages16_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_17` add INDEX `messages17_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_18` add INDEX `messages18_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_19` add INDEX `messages19_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_20` add INDEX `messages20_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_21` add INDEX `messages21_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_22` add INDEX `messages22_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_23` add INDEX `messages23_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_24` add INDEX `messages24_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_25` add INDEX `messages25_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_26` add INDEX `messages26_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_27` add INDEX `messages27_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_28` add INDEX `messages28_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_29` add INDEX `messages29_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_30` add INDEX `messages30_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_31` add INDEX `messages31_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_32` add INDEX `messages32_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_33` add INDEX `messages33_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_34` add INDEX `messages34_conv_index` (`_type`, `_target`, `_line`);
alter table `t_messages_35` add INDEX `messages35_conv_index` (`_type`, `_target`, `_line`);
@@ -0,0 +1 @@
alter table `t_channel_listener` add INDEX `channel_mid_index` (`_mid`);
+1
View File
@@ -0,0 +1 @@
alter table `t_channel` add column `_menu` BLOB DEFAULT NULL;
+10 -5
View File
@@ -5,7 +5,7 @@
<relativePath>../</relativePath>
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.87</version>
<version>0.94</version>
</parent>
<artifactId>moquette-broker</artifactId>
@@ -27,18 +27,18 @@
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.1</version>
<version>2.17.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.1</version>
<version>2.17.2</version>
</dependency>
<!--用于与slf4j保持桥接-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.17.1</version>
<version>2.17.2</version>
</dependency>
<!-- slf4j核心包-->
<dependency>
@@ -56,7 +56,7 @@
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
<version>8.0.28</version>
</dependency>
<dependency>
@@ -234,6 +234,11 @@
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>2.4.1</version>
</dependency>
</dependencies>
@@ -11,6 +11,7 @@ package cn.wildfirechat.push;
import cn.wildfirechat.common.IMExceptionEvent;
import cn.wildfirechat.proto.ProtoConstants;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.moquette.persistence.MemorySessionStore;
import io.moquette.server.config.IConfig;
import io.moquette.spi.ISessionsStore;
@@ -29,7 +30,7 @@ import static win.liyufan.im.HttpUtils.HttpPostType.POST_TYPE_Push;
public class PushServer {
private static final Logger LOG = LoggerFactory.getLogger(PushServer.class);
protected static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();
public interface PushMessageType {
int PUSH_MESSAGE_TYPE_NORMAL = 0;
int PUSH_MESSAGE_TYPE_VOIP_INVITE = 1;
@@ -100,7 +101,7 @@ public class PushServer {
url = iOSPushServerUrl;
pushMessage.voipDeviceToken = session.getVoipDeviceToken();
}
HttpUtils.httpJsonPost(url, new Gson().toJson(pushMessage, pushMessage.getClass()), POST_TYPE_Push);
HttpUtils.httpJsonPost(url, gson.toJson(pushMessage, pushMessage.getClass()), POST_TYPE_Push);
} else {
LOG.info("Not mobile platform {}", session.getPlatform());
}
@@ -9,6 +9,7 @@
package com.xiaoleilu.loServer.action;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.annotation.RequireAuthentication;
import com.xiaoleilu.loServer.handler.Request;
@@ -39,7 +40,7 @@ import static io.moquette.BrokerConstants.*;
abstract public class Action {
public static IMessagesStore messagesStore = null;
public static ISessionsStore sessionsStore = null;
protected static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();
public ChannelHandlerContext ctx;
protected static RateLimiter adminLimiter = null;
@@ -129,7 +130,7 @@ abstract public class Action {
}
RestResult result = RestResult.resultOf(errorCode, errorCode.getMsg(), RestResult.resultOf(errorCode));
response.setContent(new Gson().toJson(result));
response.setContent(gson.toJson(result));
response.send();
}
@@ -145,7 +146,7 @@ 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
Gson gson = new Gson();
T t = gson.fromJson(content, cls);
return t;
}
@@ -154,6 +155,6 @@ abstract public class Action {
protected void setResponseContent(RestResult result, Response response) {
response.setStatus(HttpResponseStatus.OK);
response.setContent(new Gson().toJson(result));
response.setContent(gson.toJson(result));
}
}
@@ -34,7 +34,7 @@ public class VersionAction extends Action {
try {
response.setContent(Utility.formatJson(new Gson().toJson(GitRepositoryState.getGitRepositoryState())));
response.setContent(Utility.formatJson(gson.toJson(GitRepositoryState.getGitRepositoryState())));
} catch (IOException e) {
e.printStackTrace();
response.setContent("{\"version\":\"unknown\"}");
@@ -34,6 +34,10 @@ abstract public class AdminAction extends Action {
SECRET_KEY = secretKey;
}
public static String getSecretKey() {
return SECRET_KEY;
}
public static void setNoCheckTime(String noCheckTime) {
try {
NO_CHECK_TIME = Boolean.parseBoolean(noCheckTime);
@@ -95,7 +99,7 @@ abstract public class AdminAction extends Action {
}
RestResult result = RestResult.resultOf(errorCode, errorCode.getMsg(), data);
response.setContent(new Gson().toJson(result));
response.setContent(gson.toJson(result));
response.send();
}
}
@@ -0,0 +1,58 @@
package com.xiaoleilu.loServer.action.admin;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputApplicationGetUserInfo;
import cn.wildfirechat.pojos.OutputApplicationUserInfo;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson;
import com.hazelcast.util.StringUtil;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.annotation.HttpMethod;
import com.xiaoleilu.loServer.annotation.Route;
import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
@Route(APIPath.User_Application_Get_UserInfo)
@HttpMethod("POST")
public class ApplicationGetUserInfoAction extends AdminAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputApplicationGetUserInfo inputUserToken = getRequestBody(request.getNettyRequest(), InputApplicationGetUserInfo.class);
RestResult result;
if (inputUserToken == null || StringUtil.isNullOrEmpty(inputUserToken.getAuthCode())) {
result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
} else {
String userId = messagesStore.verifyApplicationAuthCode(inputUserToken.getAuthCode(), "admin", ProtoConstants.ApplicationType.ApplicationType_Admin);
if(userId != null) {
OutputApplicationUserInfo outputVerifyApplicationUser = new OutputApplicationUserInfo();
outputVerifyApplicationUser.setUserId(userId);
WFCMessage.User user = messagesStore.getUserInfo(userId);
if(user != null) {
outputVerifyApplicationUser.setDisplayName(user.getDisplayName());
outputVerifyApplicationUser.setPortraitUrl(user.getPortrait());
}
result = RestResult.ok(outputVerifyApplicationUser);
} else {
result = RestResult.resultOf(ErrorCode.ERROR_CODE_TOKEN_ERROR);
}
}
response.setStatus(HttpResponseStatus.OK);
response.setContent(gson.toJson(result));
}
return true;
}
}
@@ -42,7 +42,7 @@ public class BlockUserAction extends AdminAction {
response.setStatus(HttpResponseStatus.OK);
RestResult result;
result = RestResult.resultOf(errorCode);
response.setContent(new Gson().toJson(result));
response.setContent(gson.toJson(result));
if (inputUserBlock.getStatus() == 2) {
sendApiMessage(null, null, ServerAPIHelper.KICKOFF_USER_REQUEST, inputUserBlock.getUserId().getBytes(), null);
@@ -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.InputChannelSubscribe;
import cn.wildfirechat.pojos.InputCreateChannel;
import cn.wildfirechat.pojos.InputSubscribeChannel;
import cn.wildfirechat.pojos.OutputCreateChannel;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.action.channel.ChannelAction;
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 io.netty.util.internal.StringUtil;
import win.liyufan.im.IMTopic;
@Route(APIPath.Subscribe_Channel)
@HttpMethod("POST")
public class ChannelSubscriberAction extends AdminAction {
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputSubscribeChannel inputSubscribeChannel = getRequestBody(request.getNettyRequest(), InputSubscribeChannel.class);
if (inputSubscribeChannel != null
&& !io.netty.util.internal.StringUtil.isNullOrEmpty(inputSubscribeChannel.getChannelId())
&& !io.netty.util.internal.StringUtil.isNullOrEmpty(inputSubscribeChannel.getUserId())) {
WFCMessage.ListenChannel.Builder builder = WFCMessage.ListenChannel.newBuilder().setChannelId(inputSubscribeChannel.getChannelId()).setListen(inputSubscribeChannel.getSubscribe());
sendApiMessage(response, inputSubscribeChannel.getUserId(), IMTopic.ChannelListenTopic, builder.build().toByteArray(), result -> {
ErrorCode errorCode = ErrorCode.fromCode(result[0]);
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
return new Result(ErrorCode.ERROR_CODE_SUCCESS);
} else {
return new Result(errorCode);
}
});
return false;
} else {
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
}
}
return true;
}
}
@@ -36,7 +36,7 @@ public class CheckUserOnlineAction extends AdminAction {
InputGetUserInfo inputUserId = getRequestBody(request.getNettyRequest(), InputGetUserInfo.class);
if (inputUserId == null || !StringUtil.isNullOrEmpty(inputUserId.getUserId())) {
sendApiMessage(response, inputUserId.getUserId(), ServerAPIHelper.CHECK_USER_ONLINE_REQUEST, inputUserId.getUserId().getBytes(), res -> {
OutputCheckUserOnline out = new Gson().fromJson(new String(res), OutputCheckUserOnline.class);
OutputCheckUserOnline out = gson.fromJson(new String(res), OutputCheckUserOnline.class);
return new Result(ErrorCode.ERROR_CODE_SUCCESS, out);
});
return false;
@@ -0,0 +1,52 @@
/*
* 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.InputChannelId;
import cn.wildfirechat.pojos.InputSubscribeChannel;
import cn.wildfirechat.pojos.OutputBooleanValue;
import cn.wildfirechat.pojos.OutputGetChannelInfo;
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.Check_User_Subscribe_Channel)
@HttpMethod("POST")
public class CheckUserSubscribeChannelAction extends AdminAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputSubscribeChannel inputSubscribeChannel = getRequestBody(request.getNettyRequest(), InputSubscribeChannel.class);
if (inputSubscribeChannel != null
&& !StringUtil.isNullOrEmpty(inputSubscribeChannel.getChannelId())
&& !StringUtil.isNullOrEmpty(inputSubscribeChannel.getUserId())) {
boolean isInChannel = messagesStore.checkUserInChannel(inputSubscribeChannel.getUserId(), inputSubscribeChannel.getChannelId());
OutputBooleanValue outputBooleanValue = new OutputBooleanValue();
outputBooleanValue.value = isInChannel;
setResponseContent(RestResult.ok(outputBooleanValue), response);
} else {
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
}
}
return true;
}
}
@@ -39,7 +39,7 @@ public class CreateChatroomAction extends AdminAction {
FullHttpRequest fullHttpRequest = (FullHttpRequest)request.getNettyRequest();
byte[] bytes = Utils.readBytesAndRewind(fullHttpRequest.content());
String content = new String(bytes);
Gson gson = new Gson();
InputCreateChatroom inputCreateChatroom = gson.fromJson(content, InputCreateChatroom.class);
if (inputCreateChatroom != null
&& !StringUtil.isNullOrEmpty(inputCreateChatroom.getTitle())) {
@@ -67,7 +67,7 @@ public class CreateRobotAction extends AdminAction {
Utility.printExecption(LOG, e, IMExceptionEvent.EventType.ADMIN_API_Exception);
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.ERROR_CODE_SERVER_ERROR, e.getMessage());
response.setContent(new Gson().toJson(result));
response.setContent(gson.toJson(result));
return true;
}
@@ -37,7 +37,7 @@ public class DestoryChatroomAction extends AdminAction {
FullHttpRequest fullHttpRequest = (FullHttpRequest)request.getNettyRequest();
byte[] bytes = Utils.readBytesAndRewind(fullHttpRequest.content());
String content = new String(bytes);
Gson gson = new Gson();
InputDestoryChatroom inputDestoryChatroom = gson.fromJson(content, InputDestoryChatroom.class);
if (inputDestoryChatroom != null
&& !StringUtil.isNullOrEmpty(inputDestoryChatroom.getChatroomId())) {
@@ -0,0 +1,63 @@
/*
* 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.InputRobotId;
import cn.wildfirechat.pojos.OutputRobot;
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_Robot_Info)
@HttpMethod("POST")
public class GetRobotAction extends AdminAction {
@Override
public boolean isTransactionAction() {
return true;
}
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputRobotId inputUserId = getRequestBody(request.getNettyRequest(), InputRobotId.class);
if (inputUserId != null
&& (!StringUtil.isNullOrEmpty(inputUserId.getRobotId()))) {
WFCMessage.User user = messagesStore.getUserInfo(inputUserId.getRobotId());
WFCMessage.Robot robot = messagesStore.getRobot(inputUserId.getRobotId());
RestResult result;
if (user == null || robot == null) {
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
} else {
OutputRobot outputRobot = new OutputRobot();
outputRobot.fromUser(user);
outputRobot.fromRobot(robot, true);
result = RestResult.ok(outputRobot);
}
setResponseContent(result, response);
} else {
setResponseContent(RestResult.resultOf(ErrorCode.INVALID_PARAMETER), response);
}
}
return true;
}
}
@@ -50,7 +50,7 @@ public class ModifyGroupMemberExtraAction extends AdminAction {
} else {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
response.setContent(new Gson().toJson(result));
response.setContent(gson.toJson(result));
}
}
return true;
@@ -0,0 +1,59 @@
/*
* 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.channel;
import cn.wildfirechat.common.APIPath;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.pojos.InputApplicationGetUserInfo;
import cn.wildfirechat.pojos.OutputApplicationUserInfo;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.annotation.HttpMethod;
import com.xiaoleilu.loServer.annotation.Route;
import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.internal.StringUtil;
@Route(APIPath.Channel_Application_Get_UserInfo)
@HttpMethod("POST")
public class ApplicationGetUserInfoAction extends ChannelAction {
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputApplicationGetUserInfo inputUserToken = getRequestBody(request.getNettyRequest(), InputApplicationGetUserInfo.class);
RestResult result;
if (inputUserToken == null || StringUtil.isNullOrEmpty(inputUserToken.getAuthCode())) {
result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
} else {
String userId = messagesStore.verifyApplicationAuthCode(inputUserToken.getAuthCode(), channelInfo.getTargetId(), ProtoConstants.ApplicationType.ApplicationType_Channel);
if(userId != null) {
OutputApplicationUserInfo outputVerifyApplicationUser = new OutputApplicationUserInfo();
outputVerifyApplicationUser.setUserId(userId);
WFCMessage.User user = messagesStore.getUserInfo(userId);
if(user != null) {
outputVerifyApplicationUser.setDisplayName(user.getDisplayName());
outputVerifyApplicationUser.setPortraitUrl(user.getPortrait());
}
result = RestResult.ok(outputVerifyApplicationUser);
} else {
result = RestResult.resultOf(ErrorCode.ERROR_CODE_APPLICATION_TOKEN_ERROR_OR_TIMEOUT);
}
}
response.setStatus(HttpResponseStatus.OK);
response.setContent(gson.toJson(result));
}
return true;
}
}
@@ -101,7 +101,7 @@ abstract public class ChannelAction extends Action {
}
RestResult result = RestResult.resultOf(errorCode, errorCode.getMsg(), data);
response.setContent(new Gson().toJson(result));
response.setContent(gson.toJson(result));
response.send();
}
@@ -110,7 +110,7 @@ abstract public class ChannelAction extends Action {
FullHttpRequest fullHttpRequest = (FullHttpRequest) request;
byte[] bytes = Utils.readBytesAndRewind(fullHttpRequest.content());
String content = new String(bytes, StandardCharsets.UTF_8);
Gson gson = new Gson();
T t = gson.fromJson(content, cls);
return t;
}
@@ -38,7 +38,7 @@ public class SubscriberChannelAction extends ChannelAction {
if(input.getSubscribe() > 0 && (channelInfo.getStatus() & ProtoConstants.ChannelState.Channel_State_Mask_Active_Subscribe) == 0) {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_RIGHT);
response.setContent(new Gson().toJson(result));
response.setContent(gson.toJson(result));
return true;
}
WFCMessage.ListenChannel listenChannel = WFCMessage.ListenChannel.newBuilder().setChannelId(channelInfo.getTargetId()).setListen(input.getSubscribe()).build();
@@ -0,0 +1,59 @@
/*
* 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.InputApplicationGetUserInfo;
import cn.wildfirechat.pojos.OutputApplicationUserInfo;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson;
import com.xiaoleilu.loServer.RestResult;
import com.xiaoleilu.loServer.annotation.HttpMethod;
import com.xiaoleilu.loServer.annotation.Route;
import com.xiaoleilu.loServer.handler.Request;
import com.xiaoleilu.loServer.handler.Response;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.internal.StringUtil;
@Route(APIPath.Robot_Application_Get_UserInfo)
@HttpMethod("POST")
public class ApplicationGetUserInfoAction extends RobotAction {
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
InputApplicationGetUserInfo inputUserToken = getRequestBody(request.getNettyRequest(), InputApplicationGetUserInfo.class);
RestResult result;
if (inputUserToken == null || StringUtil.isNullOrEmpty(inputUserToken.getAuthCode())) {
result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
} else {
String userId = messagesStore.verifyApplicationAuthCode(inputUserToken.getAuthCode(), robot.getUid(), ProtoConstants.ApplicationType.ApplicationType_Robot);
if(userId != null) {
OutputApplicationUserInfo outputVerifyApplicationUser = new OutputApplicationUserInfo();
outputVerifyApplicationUser.setUserId(userId);
WFCMessage.User user = messagesStore.getUserInfo(userId);
if(user != null) {
outputVerifyApplicationUser.setDisplayName(user.getDisplayName());
outputVerifyApplicationUser.setPortraitUrl(user.getPortrait());
}
result = RestResult.ok(outputVerifyApplicationUser);
} else {
result = RestResult.resultOf(ErrorCode.ERROR_CODE_APPLICATION_TOKEN_ERROR_OR_TIMEOUT);
}
}
response.setStatus(HttpResponseStatus.OK);
response.setContent(gson.toJson(result));
}
return true;
}
}
@@ -0,0 +1,46 @@
/*
* 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.InputGetUserInfo;
import cn.wildfirechat.pojos.InputOutputUserInfo;
import cn.wildfirechat.pojos.OutputRobot;
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.Robot_Get_Profile)
@HttpMethod("POST")
public class GetProfileAction extends RobotAction {
@Override
public boolean action(Request request, Response response) {
if (request.getNettyRequest() instanceof FullHttpRequest) {
WFCMessage.User user = messagesStore.getUserInfo(robot.getUid());
RestResult result;
if (user == null) {
result = RestResult.resultOf(ErrorCode.ERROR_CODE_NOT_EXIST);
} else {
OutputRobot outputRobot = new OutputRobot();
outputRobot.fromUser(user);
outputRobot.fromRobot(robot, false);
result = RestResult.ok(outputRobot);
}
setResponseContent(result, response);
}
return true;
}
}
@@ -53,7 +53,7 @@ public class ModifyGroupMemberExtraAction extends RobotAction {
} else {
response.setStatus(HttpResponseStatus.OK);
RestResult result = RestResult.resultOf(ErrorCode.INVALID_PARAMETER);
response.setContent(new Gson().toJson(result));
response.setContent(gson.toJson(result));
}
}
return true;
@@ -102,7 +102,7 @@ abstract public class RobotAction extends Action {
}
RestResult result = RestResult.resultOf(errorCode, errorCode.getMsg(), data);
response.setContent(new Gson().toJson(result));
response.setContent(gson.toJson(result));
response.send();
}
@@ -113,7 +113,7 @@ abstract public class RobotAction extends Action {
String content = null;
try {
content = new String(bytes, "UTF-8");
Gson gson = new Gson();
T t = gson.fromJson(content, cls);
return t;
} catch (UnsupportedEncodingException e) {
@@ -114,6 +114,13 @@ abstract public class ActionHandler extends SimpleChannelInboundHandler<FullHttp
handleOptions(ctx, request, response);
return;
}
if ("HEAD".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpResponseStatus.OK);
response.send();
return;
}
Action action;
if (isValidePath(request.getPath())) {
action = ServerSetting.getAction(request.getPath(), request.getMethod().toUpperCase());
@@ -41,6 +41,7 @@ import io.netty.handler.codec.http.LastHttpContent;
import io.netty.handler.codec.http.cookie.Cookie;
import io.netty.handler.codec.http.cookie.DefaultCookie;
import io.netty.handler.codec.http.cookie.ServerCookieEncoder;
import org.apache.tika.Tika;
import org.slf4j.LoggerFactory;
/**
@@ -469,7 +470,9 @@ public class Response {
this.setContentLength(fileLength);
//文件类型
String contentType = HttpUtil.getMimeType(file.getName());
Tika tika = new Tika();
String contentType = tika.detect(file);
// String contentType = HttpUtil.getMimeType(file.getName());
if(StrUtil.isBlank(contentType)){
//无法识别默认使用数据流
contentType = "application/octet-stream";
@@ -120,16 +120,19 @@ public final class BrokerConstants {
public static final String SENSITIVE_Remote_Fail_When_Matched = "sensitive.remote_fail_when_matched";
public static final String MESSAGE_Forward_Url = "message.forward.url";
public static final String MESSAGE_Sensitive_Forward_Url = "message.sensitive.forward.url";
public static final String MESSAGE_Forward_Types = "message.forward.types";
public static final String MESSAGE_MentionMsg_Forward_Url = "message.mentionmsg.forward.url";
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_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";
public static final String MESSAGE_ROAMING = "message.roaming";
public static final String MESSAGE_Compensate_Time_Limit = "message.compensate_time_limit";
public static final String MESSAGE_Remote_History_Message = "message.remote_history_message";
public static final String MESSAGE_Remote_Chatroom_History_Message = "message.chatroom_remote_history_message";
@@ -141,6 +144,10 @@ public final class BrokerConstants {
public static final String MESSAGE_NO_Forward_Admin_Message = "message.no_forward_admin_message";
public static final String MESSAGE_Forward_With_Client_Info = "message.forward_with_client_info";
public static final String ROBOT_Callback_With_Client_Info = "robot.callback_with_client_info";
public static final String CHANNEL_Callback_With_Client_Info = "channel.callback_with_client_info";
public static final String FRIEND_Disable_Search = "friend.disable_search";
public static final String FRIEND_Disable_NickName_Search = "friend.disable_nick_name_search";
public static final String FRIEND_Disable_Friend_Request = "friend.disable_friend_request";
@@ -27,8 +27,6 @@ public class ChannelListenMember extends IMHandler<WFCMessage.ListenChannel> {
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
WFCMessage.ModifyUserSettingReq modifyUserSettingReq = WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingListenedChannels).setKey(request.getChannelId()).setValue(request.getListen() > 0 ? "1" : "0").build();
mServer.onApiMessage(fromUser, null, modifyUserSettingReq.toByteArray(), 0, fromUser, PutUserSettingTopic, requestSourceType);
publisher.notifyChannelListenStatusChanged(m_messagesStore.getChannelInfo(request.getChannelId()), fromUser, request.getListen() > 0);
}
return errorCode;
}
@@ -0,0 +1,28 @@
/*
* 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.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.ApplicationConfigRequestTopic)
public class ConfigApplicationHandler extends IMHandler<WFCMessage.ApplicationConfigRequest> {
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.ApplicationConfigRequest request, Qos1PublishHandler.IMCallback callback) {
ErrorCode errorCode = m_messagesStore.configApplication(request.getAppId(), request.getAppType(), request.getTimestamp(), request.getNonce(), request.getSignature());
return errorCode;
}
}
@@ -21,6 +21,9 @@ import win.liyufan.im.IMTopic;
public class CreateGroupHandler extends GroupHandler<WFCMessage.CreateGroupRequest> {
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.CreateGroupRequest request, Qos1PublishHandler.IMCallback callback) {
if(request.getGroup().getGroupInfo().getType() < 0 || request.getGroup().getGroupInfo().getType() > 2) {
return ErrorCode.ERROR_CODE_INVALID_DATA;
}
if (!StringUtil.isNullOrEmpty(request.getGroup().getGroupInfo().getTargetId())) {
WFCMessage.GroupInfo existGroupInfo = m_messagesStore.getGroupInfo(request.getGroup().getGroupInfo().getTargetId());
@@ -19,11 +19,11 @@ import static win.liyufan.im.IMTopic.PutUserSettingTopic;
import static win.liyufan.im.UserSettingScope.kUserSettingMyChannels;
@Handler(value = IMTopic.DestroyChannelInfoTopic)
public class DistroyChannelHandler extends GroupHandler<WFCMessage.IDBuf> {
public class DestroyChannelHandler extends GroupHandler<WFCMessage.IDBuf> {
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.IDBuf request, Qos1PublishHandler.IMCallback callback) {
boolean isAdmin = requestSourceType == ProtoConstants.RequestSourceType.Request_From_Admin;
ErrorCode errorCode = m_messagesStore.distoryChannel(fromUser, request.getId(), isAdmin);
ErrorCode errorCode = m_messagesStore.destroyChannel(fromUser, request.getId(), isAdmin);
if (errorCode == ErrorCode.ERROR_CODE_SUCCESS) {
WFCMessage.ModifyUserSettingReq modifyUserSettingReq = WFCMessage.ModifyUserSettingReq.newBuilder().setScope(kUserSettingMyChannels).setKey(request.getId()).setValue("0").build();
mServer.onApiMessage(fromUser, null, modifyUserSettingReq.toByteArray(), 0, fromUser, PutUserSettingTopic, requestSourceType);
@@ -0,0 +1,33 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package io.moquette.imhandler;
import cn.wildfirechat.common.ErrorCode;
import cn.wildfirechat.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.GetApplicationTokenRequestTopic)
public class GetApplicationTokenHandler extends IMHandler<WFCMessage.AuthCodeRequest> {
@Override
public ErrorCode action(ByteBuf ackPayload, String clientID, String fromUser, ProtoConstants.RequestSourceType requestSourceType, WFCMessage.AuthCodeRequest request, Qos1PublishHandler.IMCallback callback) {
String authCode = m_messagesStore.getApplicationAuthCode(fromUser, request.getTargetId(), request.getType(), request.getHost());
if(authCode != null) {
byte[] data = WFCMessage.IDBuf.newBuilder().setId(authCode).build().toByteArray();
ackPayload.ensureWritable(data.length).writeBytes(data);
return ERROR_CODE_SUCCESS;
}
return ErrorCode.INVALID_PARAMETER;
}
}
@@ -26,6 +26,7 @@ public class GetQiniuUploadTokenHandler extends IMHandler<Byte> {
String token;
WFCMessage.GetUploadTokenResult.Builder resultBuilder = WFCMessage.GetUploadTokenResult.newBuilder();
if (MediaServerConfig.USER_QINIU) {
Auth auth = Auth.create(MediaServerConfig.QINIU_ACCESS_KEY, MediaServerConfig.QINIU_SECRET_KEY);
@@ -25,6 +25,7 @@ import io.netty.util.internal.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.wildfirechat.common.ErrorCode;
import win.liyufan.im.GsonUtil;
import win.liyufan.im.RateLimiter;
import win.liyufan.im.Utility;
@@ -39,6 +40,8 @@ import java.util.*;
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_OVER_FREQUENCY;
import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
import static io.moquette.BrokerConstants.CLIENT_REQUEST_RATE_LIMIT;
import static win.liyufan.im.IMTopic.GetUserSettingTopic;
import static win.liyufan.im.IMTopic.PullMessageTopic;
/**
* 请求处理接口<br>
@@ -139,7 +142,7 @@ abstract public class IMHandler<T> {
// }
//json ?
return (T)(new Gson().fromJson(new String(bytes), dataCls));
return (T)(GsonUtil.gson.fromJson(new String(bytes), dataCls));
}
public static void init(IMessagesStore ms, ISessionsStore ss, MessagesPublisher p, ThreadPoolExecutorWrapper businessExecutor, Server server) {
@@ -162,18 +165,17 @@ abstract public class IMHandler<T> {
mLimitCounter = new RateLimiter(5, clientRateLimit);
}
boolean isNotLimitTopic(String topic) {
if (PullMessageTopic.equals(topic)
|| GetUserSettingTopic.equals(topic)) {
return true;
}
return false;
}
public ErrorCode preAction(String clientID, String fromUser, String topic, Qos1PublishHandler.IMCallback callback, ProtoConstants.RequestSourceType requestSourceType) {
LOG.info("imHandler fromUser={}, clientId={}, topic={}", fromUser, clientID, topic);
if(requestSourceType == ProtoConstants.RequestSourceType.Request_From_User && !mLimitCounter.isGranted(clientID + fromUser + topic)) {
ByteBuf ackPayload = Unpooled.buffer();
ackPayload.ensureWritable(1).writeByte(ERROR_CODE_OVER_FREQUENCY.getCode());
try {
callback.onIMHandled(ERROR_CODE_OVER_FREQUENCY, ackPayload);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
if(requestSourceType == ProtoConstants.RequestSourceType.Request_From_User && !isNotLimitTopic(topic) && !mLimitCounter.isGranted(clientID + fromUser + topic)) {
return ErrorCode.ERROR_CODE_OVER_FREQUENCY;
}
return ErrorCode.ERROR_CODE_SUCCESS;
@@ -34,7 +34,7 @@ public class RecallMessageHandler extends IMHandler<WFCMessage.INT64Buf> {
return ErrorCode.ERROR_CODE_NOT_EXIST;
}
publish(fromUser, clientID, message, requestSourceType);
publish(message.getFromUser(), clientID, message, requestSourceType);
return errorCode;
}
@@ -9,19 +9,18 @@
package io.moquette.imhandler;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.pojos.OutputClient;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson;
import com.hazelcast.util.StringUtil;
import io.moquette.BrokerConstants;
import io.moquette.persistence.MemorySessionStore;
import io.moquette.spi.impl.Qos1PublishHandler;
import io.netty.buffer.ByteBuf;
import cn.wildfirechat.common.ErrorCode;
import io.netty.buffer.Unpooled;
import win.liyufan.im.HttpUtils;
import win.liyufan.im.IMTopic;
import win.liyufan.im.MessageShardingUtil;
import win.liyufan.im.Utility;
import win.liyufan.im.*;
import java.util.HashSet;
import java.util.Set;
@@ -32,6 +31,7 @@ import static cn.wildfirechat.common.ErrorCode.ERROR_CODE_SUCCESS;
public class SendMessageHandler 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 String mMentionForwardUrl = null;
private int mBlacklistStrategy = 0; //黑名单中时,0失败,1吞掉。
@@ -54,7 +54,7 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
}
}
}
mSensitiveMessageForwardUrl = mServer.getConfig().getProperty(BrokerConstants.MESSAGE_Sensitive_Forward_Url);
mMentionForwardUrl = mServer.getConfig().getProperty(BrokerConstants.MESSAGE_MentionMsg_Forward_Url);
try {
@@ -171,12 +171,20 @@ 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)) {
publisher.forwardMessage(message, mForwardUrl);
publisher.forwardMessage(message, mForwardUrl, outputClient);
}
if(!StringUtil.isNullOrEmpty(mMentionForwardUrl) && message.hasContent() && message.getContent().getMentionedType() != 0 && !(isAdmin && mNoForwardAdminMessage)) {
publisher.forwardMessage(message, mMentionForwardUrl);
publisher.forwardMessage(message, mMentionForwardUrl, outputClient);
}
if (!isAdmin) {
@@ -184,6 +192,9 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
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, outputClient);
}
if (mSensitiveType == 0) {
errorCode = ErrorCode.ERROR_CODE_SENSITIVE_MATCHED;
} else if (mSensitiveType == 1) {
@@ -205,7 +216,7 @@ public class SendMessageHandler extends IMHandler<WFCMessage.Message> {
if(StringUtil.isNullOrEmpty(content)) {
saveAndPublish(fromUser, clientID, finalMsg, requestSourceType);
} else {
MessagePayload payload = new Gson().fromJson(content, MessagePayload.class);
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);
@@ -994,7 +994,7 @@ public class DatabaseStore {
}
sb.append(")");
sb.append(" and _scope = 6 and _key = ?");
sb.append(" and _scope in (5,6,26) and _key = ?");
statement = connection.prepareStatement(sb.toString());
int index = 1;
@@ -1142,23 +1142,21 @@ public class DatabaseStore {
try {
connection = DBUtil.getConnection();
StringBuilder sb = new StringBuilder("delete from t_user_setting where _scope in (1,3,5,7) and _uid in (");
StringBuilder sb = new StringBuilder("delete from t_user_setting where _scope in (1,3,5,6,7,19) and _uid in (");
for (int i = 0; i < users.size(); i++) {
sb.append("?");
if (i != users.size() - 1) {
sb.append(",");
}
}
sb.append(") and _key like '1-_-");
sb.append(groupId);
sb.append("'");
sb.append(") and _key like ?");
statement = connection.prepareStatement(sb.toString());
int index = 1;
for (String userId:users) {
statement.setString(index++, userId);
}
statement.setString(index++, "1-_-" + groupId);
int count = statement.executeUpdate();
LOG.info("Update rows {}", count);
@@ -2974,7 +2972,8 @@ public class DatabaseStore {
", `_secret`" +
", `_callback`" +
", `_automatic`" +
", `_dt`) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" +
", `_menu`" +
", `_dt`) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" +
" ON DUPLICATE KEY UPDATE `_name`=?" +
", `_portrait`=?" +
", `_owner`=?" +
@@ -2984,12 +2983,20 @@ public class DatabaseStore {
", `_secret`=?" +
", `_callback`=?" +
", `_automatic`=?" +
", `_menu`=?" +
", `_dt`=?";
statement = connection.prepareStatement(sql);
int index = 1;
WFCMessage.ChannelMenuList.Builder builder = WFCMessage.ChannelMenuList.newBuilder();
if (!channelInfo.getMenuList().isEmpty()) {
for (WFCMessage.ChannelMenu menuBtn:channelInfo.getMenuList()) {
builder.addMenu(menuBtn);
}
}
byte[] menuBytes = builder.build().toByteArray();
int index = 1;
statement.setString(index++, channelInfo.getTargetId());
statement.setString(index++, channelInfo.getName());
statement.setString(index++, channelInfo.getPortrait());
@@ -3000,6 +3007,7 @@ public class DatabaseStore {
statement.setString(index++, channelInfo.getSecret());
statement.setString(index++, channelInfo.getCallback());
statement.setInt(index++, channelInfo.getAutomatic());
statement.setBytes(index++, menuBytes);
statement.setLong(index++, channelInfo.getUpdateDt() == 0 ? System.currentTimeMillis() : channelInfo.getUpdateDt());
statement.setString(index++, channelInfo.getName());
@@ -3011,6 +3019,7 @@ public class DatabaseStore {
statement.setString(index++, channelInfo.getSecret());
statement.setString(index++, channelInfo.getCallback());
statement.setInt(index++, channelInfo.getAutomatic());
statement.setBytes(index++, menuBytes);
statement.setLong(index++, channelInfo.getUpdateDt() == 0 ? System.currentTimeMillis() : channelInfo.getUpdateDt());
int count = statement.executeUpdate();
@@ -3063,6 +3072,7 @@ public class DatabaseStore {
", `_secret`" +
", `_callback`" +
", `_automatic`" +
", `_menu`" +
", `_dt` from t_channel where `_cid` = ?";
statement = connection.prepareStatement(sql);
@@ -3113,6 +3123,21 @@ public class DatabaseStore {
intValue = rs.getInt(index++);
builder.setAutomatic(intValue);
try {
byte[] bytes = null;
Blob blob = rs.getBlob(index++);
if (blob != null) {
bytes = toByteArray(blob.getBinaryStream());
}
WFCMessage.ChannelMenuList menuButtonList = WFCMessage.ChannelMenuList.parseFrom(bytes);
if (menuButtonList.getMenuCount() > 0) {
builder.addAllMenu(menuButtonList.getMenuList());
}
} catch (IOException e) {
e.printStackTrace();
}
long longValue = rs.getLong(index++);
builder.setUpdateDt(longValue);
@@ -3334,6 +3359,57 @@ public class DatabaseStore {
});
}
List<String> getUserChannels(String userId) {
List<String> out = new ArrayList<>();
Connection connection = null;
PreparedStatement statement = null;
ResultSet rs = null;
try {
connection = DBUtil.getConnection();
String sql = "select _cid from t_channel_listener where _mid = ?";
statement = connection.prepareStatement(sql);
int index = 1;
statement.setString(index++, userId);
rs = statement.executeQuery();
while (rs.next()) {
String value = rs.getString(1);
if (!StringUtil.isNullOrEmpty(value)) {
out.add(value);
}
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement, rs);
}
return out;
}
void clearChannelListener(final String channelId) {
LOG.info("Database remove channel {}", channelId);
Connection connection = null;
PreparedStatement statement = null;
try {
connection = DBUtil.getConnection();
String sql = "delete from t_channel_listener where _cid=?";
statement = connection.prepareStatement(sql);
statement.setString(1, channelId);
int count = statement.executeUpdate();
LOG.info("Update rows {}", count);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Utility.printExecption(LOG, e, RDBS_Exception);
} finally {
DBUtil.closeDB(connection, statement);
}
}
public Set<String> getSensitiveWord() {
Connection connection = null;
PreparedStatement statement = null;
@@ -23,6 +23,7 @@ import com.google.gson.Gson;
import com.google.protobuf.ByteString;
import com.hazelcast.core.*;
import com.hazelcast.util.StringUtil;
import com.xiaoleilu.loServer.action.admin.AdminAction;
import com.xiaoleilu.loServer.model.FriendData;
import cn.wildfirechat.common.ErrorCode;
import io.moquette.BrokerConstants;
@@ -31,14 +32,18 @@ import io.moquette.server.Constants;
import io.moquette.server.Server;
import io.moquette.spi.IMatchingCondition;
import io.moquette.spi.IMessagesStore;
import io.moquette.spi.impl.security.AES;
import io.moquette.spi.security.Tokenor;
import io.moquette.spi.impl.subscriptions.Topic;
import io.netty.handler.codec.mqtt.MqttVersion;
import org.apache.commons.codec.digest.DigestUtils;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import win.liyufan.im.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
@@ -91,6 +96,7 @@ public class MemoryMessagesStore implements IMessagesStore {
private static final String CHANNEL_LISTENERS = "channel_listeners";
private static boolean IS_MESSAGE_ROAMING = true;
private static long msgCompensateTimeLimit = 300000;
private static boolean IS_MESSAGE_REMOTE_HISTORY_MESSAGE = true;
private static boolean IS_CHATROOM_MESSAGE_REMOTE_HISTORY_MESSAGE = true;
@@ -162,6 +168,10 @@ public class MemoryMessagesStore implements IMessagesStore {
private int mSyncDataPartSize = 0;
private boolean keepDisplayNameWhenDestroyUser = true;
private boolean mForwardMessageWithClientInfo = false;
private boolean mRobotCallbackWithClientInfo = false;
private boolean mChannelCallbackWithClientInfo = false;
private Set<Integer> mUserHideProperties = new HashSet<>();
MemoryMessagesStore(Server server, DatabaseStore databaseStore) {
@@ -169,6 +179,11 @@ public class MemoryMessagesStore implements IMessagesStore {
this.databaseStore = databaseStore;
IS_MESSAGE_ROAMING = "1".equals(m_Server.getConfig().getProperty(MESSAGE_ROAMING));
try {
msgCompensateTimeLimit = Long.parseLong(m_Server.getConfig().getProperty(MESSAGE_Compensate_Time_Limit, "300000"));
} catch (NumberFormatException e) {
}
IS_MESSAGE_REMOTE_HISTORY_MESSAGE = "1".equals(m_Server.getConfig().getProperty(MESSAGE_Remote_History_Message));
IS_CHATROOM_MESSAGE_REMOTE_HISTORY_MESSAGE = "1".equals(m_Server.getConfig().getProperty(MESSAGE_Remote_Chatroom_History_Message, "1"));
Constants.MAX_MESSAGE_QUEUE = Integer.parseInt(m_Server.getConfig().getProperty(MESSAGE_Max_Queue));
@@ -442,6 +457,21 @@ public class MemoryMessagesStore implements IMessagesStore {
e.printStackTrace();
}
try {
mForwardMessageWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.MESSAGE_Forward_With_Client_Info, "false"));
} catch (Exception e) {
}
try {
mRobotCallbackWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.ROBOT_Callback_With_Client_Info, "false"));
} catch (Exception e) {
}
try {
mChannelCallbackWithClientInfo = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.CHANNEL_Callback_With_Client_Info, "false"));
} catch (Exception e) {
}
}
@@ -564,8 +594,7 @@ public class MemoryMessagesStore implements IMessagesStore {
if (channelInfo != null) {
if (channelInfo.getOwner().equals(fromUser)) {
if(requestSourceType == ProtoConstants.RequestSourceType.Request_From_Channel
&& !StringUtil.isNullOrEmpty(channelInfo.getCallback())
&& channelInfo.getAutomatic() == 1) {
&& channelInfo.getAutomatic() != 0) {
LOG.info("Channel api message not send to the owner when automatic");
} else {
notifyReceivers.add(fromUser);
@@ -595,8 +624,10 @@ public class MemoryMessagesStore implements IMessagesStore {
}
} else {
notifyReceivers.add(fromUser);
if (StringUtil.isNullOrEmpty(channelInfo.getCallback()) || channelInfo.getAutomatic() == 0) {
if (channelInfo.getAutomatic() == 0) {
notifyReceivers.add(channelInfo.getOwner());
} else {
LOG.info("Channel api message not send to the owner when automatic");
}
}
} else {
@@ -714,7 +745,7 @@ public class MemoryMessagesStore implements IMessagesStore {
}
}
if (noRoaming && (System.currentTimeMillis() - bundle.getMessage().getServerTimestamp() > 5 * 60 * 1000)) {
if (noRoaming && (System.currentTimeMillis() - bundle.getMessage().getServerTimestamp() > msgCompensateTimeLimit)) {
continue;
}
@@ -1112,7 +1143,7 @@ public class MemoryMessagesStore implements IMessagesStore {
event.type = type;
m_Server.getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(mGroupInfoUpdateCallback, new Gson().toJson(event), HttpUtils.HttpPostType.POST_TYPE_Grout_Event_Callback);
HttpUtils.httpJsonPost(mGroupInfoUpdateCallback, GsonUtil.gson.toJson(event), HttpUtils.HttpPostType.POST_TYPE_Grout_Event_Callback);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
@@ -1131,7 +1162,7 @@ public class MemoryMessagesStore implements IMessagesStore {
event.value = value;
m_Server.getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(mGroupMemberUpdateCallback, new Gson().toJson(event), HttpUtils.HttpPostType.POST_TYPE_Grout_Member_Event_Callback);
HttpUtils.httpJsonPost(mGroupMemberUpdateCallback, GsonUtil.gson.toJson(event), HttpUtils.HttpPostType.POST_TYPE_Grout_Member_Event_Callback);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
@@ -1149,7 +1180,7 @@ public class MemoryMessagesStore implements IMessagesStore {
event.value = value;
m_Server.getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(mRelationUpdateCallback, new Gson().toJson(event), HttpUtils.HttpPostType.POST_TYPE_User_Relation_Event_Callback);
HttpUtils.httpJsonPost(mRelationUpdateCallback, GsonUtil.gson.toJson(event), HttpUtils.HttpPostType.POST_TYPE_User_Relation_Event_Callback);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
@@ -1162,7 +1193,7 @@ public class MemoryMessagesStore implements IMessagesStore {
if (!StringUtil.isNullOrEmpty(mUserInfoUpdateCallback)) {
m_Server.getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(mUserInfoUpdateCallback, new Gson().toJson(InputOutputUserInfo.fromPbUser(user)), HttpUtils.HttpPostType.POST_TYPE_User_Info_Event_Callback);
HttpUtils.httpJsonPost(mUserInfoUpdateCallback, GsonUtil.gson.toJson(InputOutputUserInfo.fromPbUser(user)), HttpUtils.HttpPostType.POST_TYPE_User_Info_Event_Callback);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
@@ -1179,7 +1210,7 @@ public class MemoryMessagesStore implements IMessagesStore {
event.type = type;
m_Server.getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(mChannelInfoUpdateCallback, new Gson().toJson(event), HttpUtils.HttpPostType.POST_TYPE_Channel_Info_Event_Callback);
HttpUtils.httpJsonPost(mChannelInfoUpdateCallback, GsonUtil.gson.toJson(event), HttpUtils.HttpPostType.POST_TYPE_Channel_Info_Event_Callback);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
@@ -1195,7 +1226,7 @@ public class MemoryMessagesStore implements IMessagesStore {
event.type = type;
m_Server.getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(mChatroomInfoUpdateCallback, new Gson().toJson(event), HttpUtils.HttpPostType.POST_TYPE_Chatroom_Info_Event_Callback);
HttpUtils.httpJsonPost(mChatroomInfoUpdateCallback, GsonUtil.gson.toJson(event), HttpUtils.HttpPostType.POST_TYPE_Chatroom_Info_Event_Callback);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
@@ -1213,7 +1244,7 @@ public class MemoryMessagesStore implements IMessagesStore {
event.type = type;
m_Server.getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(mChatroomMemberUpdateCallback, new Gson().toJson(event), HttpUtils.HttpPostType.POST_TYPE_Chatroom_Member_Event_Callback);
HttpUtils.httpJsonPost(mChatroomMemberUpdateCallback, GsonUtil.gson.toJson(event), HttpUtils.HttpPostType.POST_TYPE_Chatroom_Member_Event_Callback);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
@@ -1275,11 +1306,31 @@ public class MemoryMessagesStore implements IMessagesStore {
}
}
MultiMap<String, WFCMessage.GroupMember> groupMembers = hzInstance.getMultiMap(GROUP_MEMBERS);
Collection<WFCMessage.GroupMember> members = groupMembers.get(groupId);
if (members == null || members.size() == 0) {
members = loadGroupMemberFromDB(hzInstance, groupId);
}
ArrayList<String> existMemberIds = new ArrayList<>();
for (WFCMessage.GroupMember member : members) {
if (member.getType() != GroupMemberType_Removed) {
existMemberIds.add(member.getMemberId());
}
}
long updateDt = System.currentTimeMillis();
List<WFCMessage.GroupMember> tmp = new ArrayList<>();
ArrayList<String> newInviteUsers = new ArrayList<>();
int newMemberCount = 0;
for (WFCMessage.GroupMember member : memberList) {
if (existMemberIds.contains(member.getMemberId()) && member.getType() != GroupMemberType_Removed) {
if(!isAdmin)
continue;
} else {
newMemberCount++;
}
WFCMessage.GroupMember.Builder builder = member.toBuilder();
builder.setUpdateDt(updateDt).setCreateDt(updateDt);
if (member.getMemberId().equals(groupInfo.getOwner())) {
@@ -1299,29 +1350,23 @@ public class MemoryMessagesStore implements IMessagesStore {
}
member = builder.build();
tmp.add(member);
newInviteUsers.add(member.getMemberId());
updateDt++;
}
memberList = tmp;
MultiMap<String, WFCMessage.GroupMember> groupMembers = hzInstance.getMultiMap(GROUP_MEMBERS);
Collection<WFCMessage.GroupMember> members = groupMembers.get(groupId);
if (members == null || members.size() == 0) {
members = loadGroupMemberFromDB(hzInstance, groupId);
}
if (maxCount != Integer.MAX_VALUE) {
int existCount = 0;
for (WFCMessage.GroupMember member : members) {
if (member.getType() != GroupMemberType_Removed) {
existCount++;
}
if (memberList.size() == 0) {
if (!isAdmin) {
return ErrorCode.ERROR_CODE_ALREADY_IN_GROUP;
} else {
return ErrorCode.ERROR_CODE_SUCCESS;
}
if (existCount + newInviteUsers.size() > maxCount) {
} else {
if (existMemberIds.size() + newMemberCount > maxCount) {
return ErrorCode.ERROR_CODE_GROUP_EXCEED_MAX_MEMBER_COUNT;
}
}
databaseStore.persistGroupMember(groupId, memberList, true);
databaseStore.updateGroupMemberCountDt(groupId);
@@ -3301,6 +3346,156 @@ public class MemoryMessagesStore implements IMessagesStore {
return true;
}
private String ensureSecretLength(String secret) {
while ( secret.length() < 16) {
secret += "w";
secret += secret;
}
return secret;
}
@Override
public String getApplicationAuthCode(String fromUser, String applicationId, int type, String host) {
String secret = null;
if(type == ProtoConstants.ApplicationType.ApplicationType_Robot) {
WFCMessage.Robot robotData = getRobot(applicationId);
if(robotData != null && !StringUtil.isNullOrEmpty(robotData.getCallback()) && !StringUtil.isNullOrEmpty(robotData.getSecret())) {
try {
URL url = new URL(robotData.getCallback());
if(url.getHost().equals(host)) {
secret = robotData.getSecret();
} else {
LOG.warn("get application auth code error, request host is not the same host with callback host");
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
} else {
String errorReason;
if(robotData == null) {
errorReason = "Robot not exist.";
} else if(StringUtil.isNullOrEmpty(robotData.getCallback())) {
errorReason = "Robot no callback address";
} else {
errorReason = "Robot no secret";
}
LOG.warn("get application auth code error, reason {}", errorReason);
}
} else if(type == ProtoConstants.ApplicationType.ApplicationType_Channel) {
WFCMessage.ChannelInfo channelData = getChannelInfo(applicationId);
if(channelData != null && !StringUtil.isNullOrEmpty(channelData.getCallback()) && !StringUtil.isNullOrEmpty(channelData.getSecret())) {
try {
URL url = new URL(channelData.getCallback());
if(url.getHost().equals(host)) {
secret = channelData.getSecret();
} else {
LOG.warn("get application auth code error, request host is not the same host with callback host");
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
} else {
String errorReason;
if(channelData == null) {
errorReason = "Channel not exist.";
} else if(StringUtil.isNullOrEmpty(channelData.getCallback())) {
errorReason = "Channel no callback address";
} else {
errorReason = "Channel no secret";
}
LOG.warn("get application auth code error, reason {}", errorReason);
}
} else if(type == ProtoConstants.ApplicationType.ApplicationType_Admin) {
secret = AdminAction.getSecretKey();
applicationId = "wfadmin";
}
if(!StringUtil.isNullOrEmpty(secret)) {
secret = ensureSecretLength(secret);
byte[] token = AES.AESEncrypt(fromUser + "?|?" + System.currentTimeMillis() + "?|?" + applicationId + "?|?" + type, secret);
return new String(Base64.getEncoder().encode(token));
}
return null;
}
@Override
public String verifyApplicationAuthCode(String authCode, String applicationId, int type) {
String secret = null;
if(type == ProtoConstants.ApplicationType.ApplicationType_Robot) {
WFCMessage.Robot robotData = getRobot(applicationId);
if(robotData != null && !StringUtil.isNullOrEmpty(robotData.getCallback()) && !StringUtil.isNullOrEmpty(robotData.getSecret())) {
secret = robotData.getSecret();
}
} else if(type == ProtoConstants.ApplicationType.ApplicationType_Channel) {
WFCMessage.ChannelInfo channelData = getChannelInfo(applicationId);
if(channelData != null && !StringUtil.isNullOrEmpty(channelData.getCallback()) && !StringUtil.isNullOrEmpty(channelData.getSecret())) {
secret = channelData.getSecret();
}
} else if(type == ProtoConstants.ApplicationType.ApplicationType_Admin) {
secret = AdminAction.getSecretKey();
applicationId = "wfadmin";
}
secret = ensureSecretLength(secret);
byte[] data = Base64.getDecoder().decode(authCode);
data = AES.AESDecrypt(data, secret, true);
if (data == null || data.length == 0) {
return null;
} else {
String str = new String(data);
String[] strArr = str.split("\\?\\|\\?");
if (strArr.length == 4) {
if (applicationId.equals(strArr[2])) {
long timestamp= Long.parseLong(strArr[1]);
if(System.currentTimeMillis() - timestamp > 60*1000) {
return null;
}
return strArr[0];
}
}
}
return null;
}
@Override
public ErrorCode configApplication(String appId, int appType, long timestamp, String nonce, String signature) {
String secret;
if(System.currentTimeMillis()/1000 - timestamp > 300) {
return ErrorCode.ERROR_CODE_SIGN_EXPIRED;
}
if(appType == ProtoConstants.ApplicationType.ApplicationType_Robot) {
WFCMessage.Robot robotData = getRobot(appId);
if(robotData != null) {
secret = robotData.getSecret();
} else {
return ErrorCode.ERROR_CODE_NOT_EXIST;
}
} else if(appType == ProtoConstants.ApplicationType.ApplicationType_Channel) {
WFCMessage.ChannelInfo channelData = getChannelInfo(appId);
if(channelData != null) {
secret = channelData.getSecret();
} else {
return ErrorCode.ERROR_CODE_NOT_EXIST;
}
} else {
LOG.error("Config application type only support 0 or 1");
return ErrorCode.INVALID_PARAMETER;
}
String str = nonce + "|" + appId + "|" + timestamp + "|" + secret;
String sign = DigestUtils.sha1Hex(str);
if(sign.equals(signature)) {
return ErrorCode.ERROR_CODE_SUCCESS;
}
return ErrorCode.ERROR_CODE_AUTH_FAILURE;
}
@Override
public boolean isNewFriendWelcomeMessage() {
return mFriendNewWelcomeMessage;
@@ -3651,7 +3846,7 @@ public class MemoryMessagesStore implements IMessagesStore {
@Override
public void clearUserChannels(String userId) {
databaseStore.getUserChannels(userId).forEach(s -> listenChannel(userId, s, false));
}
@@ -3693,9 +3888,15 @@ public class MemoryMessagesStore implements IMessagesStore {
e.printStackTrace();
Utility.printExecption(LOG, e);
}
} else if(modifyType == Modify_Channel_Menu) {
OutputGetChannelInfo.OutputMenuList outputMenuButtons = GsonUtil.gson.fromJson(value, OutputGetChannelInfo.OutputMenuList.class);
if (!outputMenuButtons.isEmpty()) {
for (OutputGetChannelInfo.OutputMenu outputMenuButton : outputMenuButtons) {
newInfoBuilder.addMenu(outputMenuButton.toPbInfo());
}
}
}
newInfoBuilder.setUpdateDt(System.currentTimeMillis());
mIMap.put(channelId, newInfoBuilder.build());
callbackChannelInfoUpdateEvent(operator, channelId, Channel_Event_Update);
@@ -3731,7 +3932,7 @@ public class MemoryMessagesStore implements IMessagesStore {
}
@Override
public ErrorCode distoryChannel(String operator, String channelId, boolean isAdmin) {
public ErrorCode destroyChannel(String operator, String channelId, boolean isAdmin) {
HazelcastInstance hzInstance = m_Server.getHazelcastInstance();
IMap<String, WFCMessage.ChannelInfo> mIMap = hzInstance.getMap(CHANNELS);
@@ -3751,6 +3952,8 @@ public class MemoryMessagesStore implements IMessagesStore {
newInfoBuilder.setStatus(oldInfo.getStatus() | Channel_State_Mask_Deleted);
newInfoBuilder.setUpdateDt(System.currentTimeMillis());
mIMap.put(channelId, newInfoBuilder.build());
databaseStore.clearChannelListener(channelId);
hzInstance.getMultiMap(CHANNEL_LISTENERS).remove(channelId);
callbackChannelInfoUpdateEvent(operator, channelId, Channel_Event_Destroy);
return ErrorCode.ERROR_CODE_SUCCESS;
@@ -3768,18 +3971,18 @@ public class MemoryMessagesStore implements IMessagesStore {
IMap<String, WFCMessage.ChannelInfo> mIMap = hzInstance.getMap(CHANNELS);
WFCMessage.ChannelInfo channelInfo = mIMap.get(channelId);
if(channelInfo != null && (channelInfo.getStatus() & ProtoConstants.ChannelState.Channel_State_Mask_Private) > 0) {
return ErrorCode.ERROR_CODE_NOT_RIGHT;
return ErrorCode.ERROR_CODE_NOT_EXIST;
}
getChannelListener(channelId);
if (listen) {
listeners.put(channelId, operator);
} else {
listeners.remove(channelId, operator);
try {
mWriteLock.lock();
databaseStore.updateChannelListener(channelId, operator, listen);
listeners.remove(channelId);
} finally {
mWriteLock.unlock();
}
databaseStore.updateChannelListener(channelId, operator, listen);
IMHandler.getPublisher().notifyChannelListenStatusChanged(channelInfo, operator, listen);
return ErrorCode.ERROR_CODE_SUCCESS;
}
@@ -3788,9 +3991,14 @@ public class MemoryMessagesStore implements IMessagesStore {
MultiMap<String, String> listeners = hzInstance.getMultiMap(CHANNEL_LISTENERS);
Collection<String> result = listeners.get(channelId);
if (result.isEmpty()) {
result = databaseStore.getChannelListener(channelId);
for (String userId : result) {
listeners.put(channelId, userId);
try {
mWriteLock.lock();
result = databaseStore.getChannelListener(channelId);
for (String userId : result) {
listeners.put(channelId, userId);
}
} finally {
mWriteLock.unlock();
}
}
return result;
@@ -3819,12 +4027,7 @@ public class MemoryMessagesStore implements IMessagesStore {
}
Collection<String> channelMembers = getChannelListener(channelId);
if (channelMembers == null) {
return false;
}
Collection<String> chatroomMembers = getChannelListener(channelId);
if (chatroomMembers == null || !chatroomMembers.contains(user)) {
if (channelMembers == null || !channelMembers.contains(user)) {
return false;
}
@@ -3850,12 +4053,7 @@ public class MemoryMessagesStore implements IMessagesStore {
@Override
public Collection<String> getChannelSubscriber(String channelId) {
MultiMap<String, String> channelMembers = m_Server.getHazelcastInstance().getMultiMap(CHANNEL_LISTENERS);
if (channelMembers == null) {
return new ArrayList<>();
}
return channelMembers.get(channelId);
return getChannelListener(channelId);
}
@Override
@@ -3915,6 +4113,20 @@ public class MemoryMessagesStore implements IMessagesStore {
return mGroupVisibleQuitKickoffNotification;
}
@Override
public boolean isForwardMessageWithClientInfo() {
return mForwardMessageWithClientInfo;
}
@Override
public boolean isRobotCallbackWithClientInfo() {
return mRobotCallbackWithClientInfo;
}
@Override
public boolean isChannelCallbackWithClientInfo() {
return mChannelCallbackWithClientInfo;
}
@Override
public List<Integer> getClientForbiddenSendTypes() {
@@ -39,6 +39,7 @@ public class MemorySessionStore implements ISessionsStore {
private static final Logger LOG = LoggerFactory.getLogger(MemorySessionStore.class);
private boolean supportMultiEndpoint = false;
private boolean supportMultiPCEndpoint = false;
private boolean clientSupportKickoff = false;
public static class Session implements Comparable<Session>{
@@ -287,6 +288,11 @@ public class MemorySessionStore implements ISessionsStore {
Utility.printExecption(LOG, e);
}
try {
supportMultiPCEndpoint = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_MULTI_PC_ENDPOINT, "false"));
} catch (Exception e) {
}
try {
clientSupportKickoff = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.SERVER_CLIENT_SUPPORT_KICKOFF_EVENT, "false"));
} catch (Exception e) {
@@ -385,7 +391,12 @@ public class MemorySessionStore implements ISessionsStore {
}
databaseStore.clearMultiUser(username, clientID);
if (!supportMultiEndpoint && platform > 0) {
if (!supportMultiEndpoint
&& platform > 0
&& !(platform == ProtoConstants.Platform.Platform_Windows && supportMultiPCEndpoint)
&& !(platform == ProtoConstants.Platform.Platform_LINUX && supportMultiPCEndpoint)
&& !(platform == ProtoConstants.Platform.Platform_OSX && supportMultiPCEndpoint)
) {
databaseStore.clearMultiEndpoint(username, clientID, platform);
if (userSessions.get(username) != null) {
Iterator<String> it = userSessions.get(username).iterator();
@@ -369,9 +369,6 @@ public class Server {
private String getServerIp(IConfig config) {
String serverIp = config.getProperty(BrokerConstants.SERVER_IP_PROPERTY_NAME);
if (serverIp == null || serverIp.equals("0.0.0.0")) {
String warning = "警告:无效配置,server.ip不能为空,需要配置服务的公网IP地址或者域名才能在公网使用!!!\nIM服务将使用本地地址,只能在局域网内使用!";
System.out.println(warning);
LOG.error(warning);
serverIp = Utility.getLocalAddress().getHostAddress();
}
return serverIp;
@@ -160,7 +160,7 @@ public class NettyAcceptor implements ServerAcceptor {
IConfig props) throws IOException {
LOG.info("Configuring TCP MQTT transport");
final MoquetteIdleTimeoutHandler timeoutHandler = new MoquetteIdleTimeoutHandler();
String host = props.getProperty(BrokerConstants.HOST_PROPERTY_NAME);
String host = props.getProperty(BrokerConstants.HOST_PROPERTY_NAME, "0.0.0.0");
String tcpPortProp = props.getProperty(PORT_PROPERTY_NAME, DISABLED_PORT_BIND);
if (DISABLED_PORT_BIND.equals(tcpPortProp)) {
LOG.info("Property {} has been set to {}. TCP MQTT will be disabled", BrokerConstants.PORT_PROPERTY_NAME,
@@ -193,6 +193,11 @@ public interface IMessagesStore {
boolean checkChatroomParticipantIdelTime(MemorySessionStore.Session session);
String getApplicationAuthCode(String fromUser, String applicationId, int appType, String host);
String verifyApplicationAuthCode(String token, String applicationId, int type);
ErrorCode configApplication(String appId, int appType, long timestamp, String nonce, String signature);
ErrorCode getUserSettings(String userId, long version, WFCMessage.GetUserSettingResult.Builder builder);
WFCMessage.UserSettingEntry getUserSetting(String userId, int scope, String key);
List<WFCMessage.UserSettingEntry> getUserSetting(String userId, int scope);
@@ -209,7 +214,7 @@ public interface IMessagesStore {
void clearUserChannels(String userId);
ErrorCode modifyChannelInfo(String operator, String channelId, int modifyType, String value);
ErrorCode transferChannel(String operator, String channelId, String newOwner);
ErrorCode distoryChannel(String operator, String channelId, boolean isAdmin);
ErrorCode destroyChannel(String operator, String channelId, boolean isAdmin);
List<WFCMessage.ChannelInfo> searchChannel(String keyword, boolean buzzy, int page);
ErrorCode listenChannel(String operator, String channelId, boolean listen);
WFCMessage.ChannelInfo getChannelInfo(String channelId);
@@ -228,6 +233,10 @@ public interface IMessagesStore {
boolean isAllowRobotCustomGroupNotification();
int getVisibleQuitKickoffNotification();
boolean isForwardMessageWithClientInfo();
boolean isRobotCallbackWithClientInfo();
boolean isChannelCallbackWithClientInfo();
List<Integer> getClientForbiddenSendTypes();
List<Integer> getBlackListExceptionTypes();
List<Integer> getGroupMuteExceptionTypes();
@@ -16,6 +16,7 @@
package io.moquette.spi.impl;
import cn.wildfirechat.pojos.OutputClient;
import cn.wildfirechat.pojos.OutputMessageData;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
@@ -24,7 +25,6 @@ import com.google.gson.Gson;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.util.StringUtil;
import cn.wildfirechat.pojos.OutputNotifyChannelSubscribeStatus;
import cn.wildfirechat.pojos.SendMessageData;
import com.xiaoleilu.loServer.model.FriendData;
import io.moquette.persistence.*;
import io.moquette.persistence.MemorySessionStore.Session;
@@ -35,6 +35,7 @@ import io.moquette.spi.ISessionsStore;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.mqtt.*;
import win.liyufan.im.GsonUtil;
import win.liyufan.im.HttpUtils;
import win.liyufan.im.IMTopic;
@@ -176,10 +177,19 @@ 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;
Server.getServer().getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(robot.getCallback(), new Gson().toJson(SendMessageData.fromProtoMessage(finalMsg), SendMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Robot_Message_Callback);
HttpUtils.httpJsonPost(robot.getCallback(), GsonUtil.gson.toJson(OutputMessageData.fromProtoMessage(finalMsg, finalOutputClient), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Robot_Message_Callback);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
@@ -595,10 +605,19 @@ public class MessagesPublisher {
public void publish2Receivers(WFCMessage.Message message, Set<String> receivers, String exceptClientId, int pullType) {
if (message.getConversation().getType() == ProtoConstants.ConversationType.ConversationType_Channel) {
WFCMessage.ChannelInfo channelInfo = m_messagesStore.getChannelInfo(message.getConversation().getTarget());
if (channelInfo != null && !StringUtil.isNullOrEmpty(channelInfo.getCallback())) {
if (channelInfo != null && !StringUtil.isNullOrEmpty(channelInfo.getCallback()) && channelInfo.getAutomatic() == 1 && !message.getFromUser().equals(channelInfo.getOwner())) {
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;
Server.getServer().getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(channelInfo.getCallback() + "/message", new Gson().toJson(SendMessageData.fromProtoMessage(message), SendMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Channel_Message_Callback);
HttpUtils.httpJsonPost(channelInfo.getCallback() + "/message", GsonUtil.gson.toJson(OutputMessageData.fromProtoMessage(message, finalOutputClient), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Channel_Message_Callback);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
@@ -627,8 +646,8 @@ public class MessagesPublisher {
pushContent = "[语音]";
} else if(type == ProtoConstants.ContentType.Video) {
pushContent = "[视频]";
} else if(type == ProtoConstants.ContentType.RichMedia) {
pushContent = "[图文]";
} else if(type == ProtoConstants.ContentType.Link) {
pushContent = "[链接]";
} else if(type == ProtoConstants.ContentType.File) {
pushContent = "[文件]";
} else if(type == ProtoConstants.ContentType.Sticker) {
@@ -648,10 +667,10 @@ public class MessagesPublisher {
}
public void forwardMessage(final WFCMessage.Message message, String forwardUrl) {
public void forwardMessage(final WFCMessage.Message message, String forwardUrl, OutputClient outputClient) {
Server.getServer().getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(forwardUrl, new Gson().toJson(OutputMessageData.fromProtoMessage(message), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Forward_Message_Callback);
HttpUtils.httpJsonPost(forwardUrl, GsonUtil.gson.toJson(OutputMessageData.fromProtoMessage(message, outputClient), OutputMessageData.class), HttpUtils.HttpPostType.POST_TYPE_Forward_Message_Callback);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
@@ -661,7 +680,7 @@ public class MessagesPublisher {
public void forwardMessageWithCallback(final WFCMessage.Message message, String forwardUrl, HttpUtils.HttpCallback callback) {
try {
HttpUtils.httpJsonPost(forwardUrl, new Gson().toJson(OutputMessageData.fromProtoMessage(message), OutputMessageData.class), new HttpUtils.HttpCallback() {
HttpUtils.httpJsonPost(forwardUrl, GsonUtil.gson.toJson(OutputMessageData.fromProtoMessage(message), OutputMessageData.class), new HttpUtils.HttpCallback() {
@Override
public void onSuccess(String content) {
Server.getServer().getImBusinessScheduler().execute(()->{
@@ -683,13 +702,13 @@ public class MessagesPublisher {
}
public void notifyChannelListenStatusChanged(WFCMessage.ChannelInfo channelInfo, String user, boolean listen) {
if (channelInfo == null || StringUtil.isNullOrEmpty(channelInfo.getCallback())) {
if (channelInfo == null || StringUtil.isNullOrEmpty(channelInfo.getCallback()) || channelInfo.getAutomatic() == 0) {
return;
}
Server.getServer().getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(channelInfo.getCallback() + "/subscribe", new Gson().toJson(new OutputNotifyChannelSubscribeStatus(user, channelInfo.getTargetId(), listen), OutputNotifyChannelSubscribeStatus.class), HttpUtils.HttpPostType.POST_TYPE_Channel_Subscriber_Event_Callback);
HttpUtils.httpJsonPost(channelInfo.getCallback() + "/subscribe", GsonUtil.gson.toJson(new OutputNotifyChannelSubscribeStatus(user, channelInfo.getTargetId(), listen), OutputNotifyChannelSubscribeStatus.class), HttpUtils.HttpPostType.POST_TYPE_Channel_Subscriber_Event_Callback);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
@@ -43,6 +43,7 @@ import io.netty.handler.codec.mqtt.*;
import io.netty.handler.timeout.IdleStateHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import win.liyufan.im.GsonUtil;
import win.liyufan.im.HttpUtils;
import win.liyufan.im.IMTopic;
import win.liyufan.im.Utility;
@@ -264,7 +265,7 @@ public class ProtocolProcessor {
if (!StringUtil.isNullOrEmpty(mUserOnlineStatusCallback)) {
mServer.getCallbackScheduler().execute(() -> {
try {
HttpUtils.httpJsonPost(mUserOnlineStatusCallback, new Gson().toJson(new UserOnlineStatus(userId, clientId, platform, status, packageName)), HttpUtils.HttpPostType.POST_TYPE_User_Online_Event_Callback);
HttpUtils.httpJsonPost(mUserOnlineStatusCallback, GsonUtil.gson.toJson(new UserOnlineStatus(userId, clientId, platform, status, packageName)), HttpUtils.HttpPostType.POST_TYPE_User_Online_Event_Callback);
} catch (Exception e) {
e.printStackTrace();
Utility.printExecption(LOG, e, EVENT_CALLBACK_Exception);
@@ -57,6 +57,7 @@ import io.netty.handler.codec.mqtt.MqttFixedHeader;
import io.netty.handler.codec.mqtt.MqttMessageType;
import io.netty.handler.codec.mqtt.MqttPublishMessage;
import cn.wildfirechat.common.ErrorCode;
import win.liyufan.im.GsonUtil;
import win.liyufan.im.IMTopic;
import win.liyufan.im.RateLimiter;
import win.liyufan.im.Utility;
@@ -142,7 +143,7 @@ public class Qos1PublishHandler extends QosPublishHandler {
out.addSession(userId, session.getClientID(), session.getPlatform(), status, session.getLastActiveTime());
}
callback.onRouteHandled(new Gson().toJson(out).getBytes());
callback.onRouteHandled(GsonUtil.gson.toJson(out).getBytes());
});
}
@@ -54,7 +54,7 @@ public class DBUtil {
if (embedDB != null && embedDB.equals("1")) {
IsEmbedDB = true;
LOG.info("Use h2 database");
String warning = "您正在使用内置h2数据库,建议仅在开发验证或者用户数小于100人时才使用此数据库,其它情况建议使用MySQL。";
String warning = "您正在使用h2数据库,建议仅在开发验证或者用户数小于100人时才使用此数据库。正式上线时建议切换到MySQL数据库。";
System.out.println(warning);
LOG.warn(warning);
} else {
@@ -0,0 +1,8 @@
package win.liyufan.im;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class GsonUtil {
public static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();
}
@@ -83,4 +83,7 @@ public interface IMTopic {
String KickoffPCClientTopic = "KPCC";
String ClearSessionTopic = "CST";
String GetApplicationTokenRequestTopic = "ATR";
String ApplicationConfigRequestTopic = "ACR";
}
@@ -98,7 +98,7 @@ public class Utility {
if(now - t >= SendExceptionDuration) {
for (Map.Entry<String, IMExceptionEvent> entry : exceptionEventHashMap.entrySet()) {
if(entry.getValue().count > 0) {
String jsonStr = new Gson().toJson(entry.getValue());
String jsonStr = GsonUtil.gson.toJson(entry.getValue());
Server.getServer().getCallbackScheduler().execute(() -> HttpUtils.httpJsonPost(gMonitorEventAddress, jsonStr, HttpUtils.HttpPostType.POST_TYPE_Server_Exception_Callback));
entry.getValue().count = 0;
lastSendTime = now;
@@ -111,7 +111,7 @@ public class Utility {
event.msg = "监控心跳通知";
event.call_stack = "别担心!这个是心跳消息,已经有24小时没有出现异常消息了!";
event.count = IMExceptionEvent.EventType.HEART_BEAT;
String jsonStr = new Gson().toJson(event);
String jsonStr = GsonUtil.gson.toJson(event);
Server.getServer().getCallbackScheduler().execute(() -> HttpUtils.httpJsonPost(gMonitorEventAddress, jsonStr, HttpUtils.HttpPostType.POST_TYPE_Server_Exception_Callback));
}
}
+8 -2
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>wildfirechat-parent</artifactId>
<groupId>cn.wildfirechat</groupId>
<version>0.87</version>
<version>0.94</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -29,7 +29,13 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
<version>2.8.9</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
@@ -26,6 +26,7 @@ public interface APIPath {
String User_Get_Token = "/admin/user/get_token";
String User_Update_Block_Status = "/admin/user/update_block_status";
String User_Get_Info = "/admin/user/get_info";
String User_Get_Robot_Info = "/admin/user/get_robot_info";
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";
@@ -34,6 +35,7 @@ public interface APIPath {
String User_Kickoff_Client = "/admin/user/kickoff_client";
String User_Online_Count = "/admin/user/online_count";
String User_Online_List = "/admin/user/online_list";
String User_Application_Get_UserInfo = "/admin/user/app_get_user_info";
String Friend_Update_Status = "/admin/friend/status";
String Friend_Get_List = "/admin/friend/list";
@@ -55,6 +57,9 @@ public interface APIPath {
String Msg_Multicast = "/admin/message/multicast";
String Msg_RecallBroadCast = "/admin/message/recall_broadcast";
String Msg_RecallMultiCast = "/admin/message/recall_multicast";
String Msg_ConvRead = "/admin/message/conv_read";
String Msg_Delivery = "/admin/message/delivery";
String Conversation_Delete = "/admin/conversation/delete";
String Create_Group = "/admin/group/create";
String Group_Dismiss = "/admin/group/del";
@@ -75,6 +80,8 @@ public interface APIPath {
String Create_Channel = "/admin/channel/create";
String Destroy_Channel = "/admin/channel/destroy";
String Get_Channel_Info = "/admin/channel/get";
String Subscribe_Channel = "/admin/channel/subscribe";
String Check_User_Subscribe_Channel = "/admin/channel/is_subscribed";
String Get_System_Setting = "/admin/system/get_setting";
String Put_System_Setting = "/admin/system/put_setting";
@@ -91,17 +98,16 @@ public interface APIPath {
String Channel_Message_Send = "/channel/message/send";
String Channel_Subscribe = "/channel/subscribe";
String Channel_Subscriber_List = "/channel/subscriber_list";
String Channel_Application_Get_UserInfo = "/channel/application/get_user_info";
String Robot_User_Info = "/robot/user_info";
String Robot_Get_Profile = "/robot/profile";
String Robot_Message_Send = "/robot/message/send";
String Robot_Set_Callback = "/robot/set_callback";
String Robot_Get_Callback = "/robot/get_callback";
String Robot_Delete_Callback = "/robot/delete_callback";
String Robot_Update_Profile = "/robot/update_profile";
String Robot_Verify_Application_User = "/robot/user/verify";
String Robot_Application_Get_UserInfo = "/robot/application/get_user_info";
String Robot_Group_Member_Add = "/robot/group/member/add";
String Robot_Group_Allow_Member = "/robot/group/manager/allow";
String Robot_Create_Group = "/robot/group/create";
@@ -28,7 +28,8 @@ public enum ErrorCode {
ERROR_CODE_INVALID_MESSAGE(10, "invalid message"),
//Group error
ERROR_CODE_GROUP_ALREADY_EXIST(11, "group aleady exist"),
ERROR_CODE_GROUP_ALREADY_EXIST(11, "group already exist"),
ERROR_CODE_ALREADY_IN_GROUP(12, "member already in group"),
//user error
ERROR_CODE_FRIEND_ALREADY_REQUEST(16, "already send request"),
@@ -50,6 +51,18 @@ public enum ErrorCode {
ERROR_CODE_CONFERENCE_ROOM_NOT_EXIST(60, "conference room not exist"),
ERROR_CODE_CONFERENCE_SERVICE_NOT_AVAILABLE(61, "conference service not available"),
ERROR_CODE_APPLICATION_TOKEN_ERROR_OR_TIMEOUT(70, "application token error or timeout"),
ERROR_CODE_SECRET_CHAT_ACCEPTED_BY_OTHER_CLIENT(81, "secret chat accepted by other client"),
ERROR_CODE_SECRET_CHAT_SESSION_NOT_EXIST(82, "secret chat session not exist"),
ERROR_CODE_SECRET_CHAT_NOT_SESSION_CLIENT(83, "not secret chat session client"),
ERROR_CODE_SECRET_CHAT_SESSION_NOT_READY(84, "secret chat session not ready"),
ERROR_CODE_SECRET_CHAT_SESSION_DESTROYED(85, "secret chat session destroyed"),
ERROR_CODE_SECRET_CHAT_MO_DISABLED(86, "origin side disable secret chat"),
ERROR_CODE_SECRET_CHAT_MT_DISABLED(87, "target side disable secret chat"),
ERROR_CODE_FUNCTION_DISABLED(220, "function disabled"),
ERROR_CODE_CHANNEL_NO_EXIST(236, "channel no exist"),
ERROR_CODE_CHANNEL_NO_SECRET(237, "channel no secret"),
ERROR_CODE_USER_NOT_PREPARED(238, "user not prepared"),
@@ -19,4 +19,5 @@ public class IMExceptionEvent {
public String msg;
public String call_stack;
public int count;
public int node_id;
}
@@ -0,0 +1,83 @@
package cn.wildfirechat.messagecontentbuilder;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import io.netty.util.internal.StringUtil;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.function.Consumer;
public class ArticlesContentBuilder extends MessageContentBuilder{
public static class Article {
public String id;
public String cover;
public String title;
public String url;
public boolean readReport;
}
public Article topArticle;
public List<Article> subArticles;
public static ArticlesContentBuilder newBuilder(String id, String cover, String title, String url, boolean readReport) {
ArticlesContentBuilder builder = new ArticlesContentBuilder();
builder.topArticle = new Article();
builder.topArticle.id = id;
builder.topArticle.cover = cover;
builder.topArticle.title = title;
builder.topArticle.url = url;
builder.topArticle.readReport = readReport;
return builder;
}
public ArticlesContentBuilder addSubArticle(String id, String cover, String title, String url, boolean readReport) {
Article article = new Article();
article.id = id;
article.cover = cover;
article.title = title;
article.url = url;
article.readReport = readReport;
if(subArticles == null) {
subArticles = new ArrayList<>();
}
subArticles.add(article);
return this;
}
private static JSONObject toJSON(Article article) {
JSONObject top = new JSONObject();
if(!StringUtil.isNullOrEmpty(article.id))
top.put("id", article.id);
if(!StringUtil.isNullOrEmpty(article.cover))
top.put("cover", article.cover);
if(!StringUtil.isNullOrEmpty(article.title))
top.put("title", article.title);
if(!StringUtil.isNullOrEmpty(article.url))
top.put("url", article.url);
if(article.readReport)
top.put("rr", article.readReport);
return top;
}
@Override
public MessagePayload build() {
MessagePayload payload = encodeBase();
payload.setType(ProtoConstants.ContentType.Articles);
payload.setPersistFlag(ProtoConstants.PersistFlag.Persist_And_Count);
payload.setSearchableContent(topArticle.title);
JSONObject jsonObject = new JSONObject();
jsonObject.put("top", toJSON(topArticle));
if(subArticles != null && !subArticles.isEmpty()) {
JSONArray jsonArray = new JSONArray();
subArticles.forEach(article -> jsonArray.add(toJSON(article)));
jsonObject.put("subArticles", jsonArray);
}
payload.setBase64edData(Base64.getEncoder().encodeToString(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8)));
return payload;
}
}
@@ -0,0 +1,19 @@
package cn.wildfirechat.messagecontentbuilder;
import cn.wildfirechat.pojos.MessagePayload;
abstract public class MediaMessageContentBuilder extends MessageContentBuilder{
private String remoteMediaUrl;
public MediaMessageContentBuilder remoteMediaUrl(String remoteMediaUrl) {
this.remoteMediaUrl = remoteMediaUrl;
return this;
}
@Override
protected MessagePayload encodeBase() {
MessagePayload payload = super.encodeBase();
payload.setRemoteMediaUrl(remoteMediaUrl);
return payload;
}
}
@@ -0,0 +1,33 @@
package cn.wildfirechat.messagecontentbuilder;
import cn.wildfirechat.pojos.MessagePayload;
import java.util.List;
public abstract class MessageContentBuilder {
private int mentionedType;
private List<String> mentionedTargets;
private String extra;
public MessageContentBuilder mentionedType(int mentionedType) {
this.mentionedType = mentionedType;
return this;
}
public MessageContentBuilder mentionedTargets(List<String> mentionedTargets) {
this.mentionedTargets = mentionedTargets;
return this;
}
public MessageContentBuilder extra(String extra) {
this.extra = extra;
return this;
}
protected MessagePayload encodeBase() {
MessagePayload payload = new MessagePayload();
payload.setMentionedType(mentionedType);
payload.setMentionedTarget(mentionedTargets);
payload.setExtra(extra);
return payload;
}
abstract public MessagePayload build();
}
@@ -0,0 +1,88 @@
package cn.wildfirechat.messagecontentbuilder;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import io.netty.util.internal.StringUtil;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class RichNotificationContentBuilder extends MessageContentBuilder{
private String title;
private String desc;
private String remark;
private JSONArray datas;
private String exName;
private String exPortrait;
private String exUrl;
private String appId;
public static RichNotificationContentBuilder newBuilder(String title, String desc, String exUrl) {
RichNotificationContentBuilder builder = new RichNotificationContentBuilder();
builder.title = title;
builder.desc = desc;
builder.exUrl = exUrl;
return builder;
}
public RichNotificationContentBuilder remark(String remark) {
this.remark = remark;
return this;
}
public RichNotificationContentBuilder exName(String exName) {
this.exName = exName;
return this;
}
public RichNotificationContentBuilder exPortrait(String exPortrait) {
this.exPortrait = exPortrait;
return this;
}
public RichNotificationContentBuilder appId(String appId) {
this.appId = appId;
return this;
}
public RichNotificationContentBuilder addItem(String key, String value) {
return addItem(key, value, null);
}
public RichNotificationContentBuilder addItem(String key, String value, String color) {
if(this.datas == null) {
this.datas = new JSONArray();
}
JSONObject item = new JSONObject();
item.put("key", key);
item.put("value", value == null ? "" : value);
if(!StringUtil.isNullOrEmpty(color)) {
item.put("color", color);
}
this.datas.add(item);
return this;
}
@Override
public MessagePayload build() {
MessagePayload payload = encodeBase();
payload.setType(ProtoConstants.ContentType.Rich_Notification);
payload.setPersistFlag(ProtoConstants.PersistFlag.Persist_And_Count);
payload.setPushContent(title);
payload.setContent(desc);
JSONObject jsonObject = new JSONObject();
if(!StringUtil.isNullOrEmpty(remark))
jsonObject.put("remark", remark);
if(!StringUtil.isNullOrEmpty(exName))
jsonObject.put("exName", exName);
if(!StringUtil.isNullOrEmpty(exPortrait))
jsonObject.put("exPortrait", exPortrait);
if(!StringUtil.isNullOrEmpty(exUrl))
jsonObject.put("exUrl", exUrl);
if(!StringUtil.isNullOrEmpty(appId))
jsonObject.put("appId", appId);
if(datas != null && !datas.isEmpty())
jsonObject.put("datas", datas);
payload.setBase64edData(Base64.getEncoder().encodeToString(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8)));
return payload;
}
}
@@ -0,0 +1,25 @@
package cn.wildfirechat.messagecontentbuilder;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
import org.json.simple.JSONObject;
public class SoundMessageContentBuilder extends MediaMessageContentBuilder {
private int duration;
public static SoundMessageContentBuilder newBuilder(int duration) {
SoundMessageContentBuilder builder = new SoundMessageContentBuilder();
builder.duration = duration;
return builder;
}
@Override
public MessagePayload build() {
MessagePayload payload = encodeBase();
payload.setType(ProtoConstants.ContentType.Voice);
payload.setMediaType(ProtoConstants.MessageMediaType.VOICE);
payload.setPersistFlag(ProtoConstants.PersistFlag.Persist_And_Count);
JSONObject jsonObject = new JSONObject();
jsonObject.put("duration", duration);
payload.setContent(jsonObject.toJSONString());
return payload;
}
}
@@ -0,0 +1,21 @@
package cn.wildfirechat.messagecontentbuilder;
import cn.wildfirechat.pojos.MessagePayload;
import cn.wildfirechat.proto.ProtoConstants;
public class TextMessageContentBuilder extends MessageContentBuilder{
private String text;
public static TextMessageContentBuilder newBuilder(String text) {
TextMessageContentBuilder builder = new TextMessageContentBuilder();
builder.text = text;
return builder;
}
@Override
public MessagePayload build() {
MessagePayload payload = encodeBase();
payload.setType(ProtoConstants.ContentType.Text);
payload.setPersistFlag(ProtoConstants.PersistFlag.Persist_And_Count);
payload.setSearchableContent(text);
return payload;
}
}
@@ -0,0 +1,54 @@
package cn.wildfirechat.pojos;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
public class ArticleContent {
public static class Article {
public String id;
public String cover;
public String title;
public String url;
public boolean rr;
public Article() {
}
public Article(String id, String cover, String title, String url, boolean rr) {
this.id = id;
this.cover = cover;
this.title = title;
this.url = url;
this.rr = rr;
}
}
public Article top;
public List<Article> subArticles;
public ArticleContent() {
}
public ArticleContent(String id, String cover, String title, String url, boolean rr) {
this.top = new Article(id, cover, title, url, rr);
}
public ArticleContent addSubArticle(String id, String cover, String title, String url, boolean rr) {
if (subArticles == null)
subArticles = new ArrayList<>();
subArticles.add(new Article(id, cover, title, url, rr));
return this;
}
public MessagePayload toPayload() {
MessagePayload payload = new MessagePayload();
payload.setType(13);
payload.setSearchableContent(top.title);
payload.setBase64edData(Base64.getEncoder().encodeToString(new GsonBuilder().disableHtmlEscaping().create().toJson(this).getBytes(StandardCharsets.UTF_8)));
return payload;
}
}
@@ -3,4 +3,5 @@ package cn.wildfirechat.pojos;
public class ConferenceJoinEvent {
public String userId;
public String roomId;
public boolean screenSharing;
}
@@ -3,4 +3,5 @@ package cn.wildfirechat.pojos;
public class ConferenceLeaveEvent {
public String userId;
public String roomId;
public boolean screenSharing;
}
@@ -4,4 +4,5 @@ public class ConferencePublishEvent {
public String userId;
public boolean video;
public String roomId;
public boolean screenSharing;
}
@@ -3,4 +3,5 @@ package cn.wildfirechat.pojos;
public class ConferenceUnpublishEvent {
public String userId;
public String roomId;
public boolean screenSharing;
}
@@ -13,6 +13,15 @@ public class Conversation {
private String target;
private int line;
public Conversation() {
}
public Conversation(int type, String target, int line) {
this.type = type;
this.target = target;
this.line = line;
}
public int getType() {
return type;
}
@@ -18,6 +18,9 @@ public class ForwardDeviceMessageData {
private int type;
private byte[] data;
public ForwardDeviceMessageData() {
}
public ForwardDeviceMessageData(String deviceId, int type, byte[] data) {
this.deviceId = deviceId;
this.type = type;
@@ -11,6 +11,7 @@ package cn.wildfirechat.pojos;
import cn.wildfirechat.proto.ProtoConstants;
import cn.wildfirechat.proto.WFCMessage;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.protobuf.ByteString;
import java.util.List;
@@ -31,6 +32,9 @@ public class GroupNotificationBinaryContent {
//value2(member or something)
private String m;
public GroupNotificationBinaryContent() {
}
public GroupNotificationBinaryContent(String g, String o, String n, String m) {
this.g = g;
this.o = o;
@@ -86,7 +90,7 @@ public class GroupNotificationBinaryContent {
}
public WFCMessage.MessageContent getGroupNotifyContent(int groupContentType) {
return WFCMessage.MessageContent.newBuilder().setType(groupContentType).setData(ByteString.copyFromUtf8(new Gson().toJson(this))).build();
return WFCMessage.MessageContent.newBuilder().setType(groupContentType).setData(ByteString.copyFromUtf8(new GsonBuilder().disableHtmlEscaping().create().toJson(this))).build();
}
public WFCMessage.MessageContent getAddGroupNotifyContent() {
@@ -8,14 +8,14 @@
package cn.wildfirechat.pojos;
public class OutputVerifyApplicationUser {
private String userId;
public class InputApplicationGetUserInfo {
private String authCode;
public String getUserId() {
return userId;
public String getAuthCode() {
return authCode;
}
public void setUserId(String userId) {
this.userId = userId;
public void setAuthCode(String authCode) {
this.authCode = authCode;
}
}
@@ -13,6 +13,9 @@ public class InputChatroomMute {
private String chatroomId;
private int status;
public InputChatroomMute() {
}
public InputChatroomMute(String chatroomId, int status) {
this.chatroomId = chatroomId;
this.status = status;
@@ -67,16 +67,18 @@ public class InputCreateGroup extends InputGroupBase {
}
groupBuilder.setGroupInfo(groupInfoBuilder);
for (PojoGroupMember pojoGroupMember : group.getMembers()) {
WFCMessage.GroupMember.Builder groupMemberBuilder = WFCMessage.GroupMember.newBuilder().setMemberId(pojoGroupMember.getMember_id());
if (!StringUtil.isNullOrEmpty(pojoGroupMember.getAlias())) {
groupMemberBuilder.setAlias(pojoGroupMember.getAlias());
if(group.getMembers() != null) {
for (PojoGroupMember pojoGroupMember : group.getMembers()) {
WFCMessage.GroupMember.Builder groupMemberBuilder = WFCMessage.GroupMember.newBuilder().setMemberId(pojoGroupMember.getMember_id());
if (!StringUtil.isNullOrEmpty(pojoGroupMember.getAlias())) {
groupMemberBuilder.setAlias(pojoGroupMember.getAlias());
}
groupMemberBuilder.setType(pojoGroupMember.getType());
if (!StringUtil.isNullOrEmpty(pojoGroupMember.getExtra())) {
groupMemberBuilder.setExtra(pojoGroupMember.extra);
}
groupBuilder.addMembers(groupMemberBuilder);
}
groupMemberBuilder.setType(pojoGroupMember.getType());
if(!StringUtil.isNullOrEmpty(pojoGroupMember.getExtra())) {
groupMemberBuilder.setExtra(pojoGroupMember.extra);
}
groupBuilder.addMembers(groupMemberBuilder);
}
WFCMessage.CreateGroupRequest.Builder createGroupReqBuilder = WFCMessage.CreateGroupRequest.newBuilder();
@@ -0,0 +1,58 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package cn.wildfirechat.pojos;
public class InputGetConvReadTime {
private String userId;
private int conversationType;
private String target;
private int line;
public InputGetConvReadTime() {
}
public InputGetConvReadTime(String userId, int conversationType, String target, int line) {
this.userId = userId;
this.conversationType = conversationType;
this.target = target;
this.line = line;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public int getConversationType() {
return conversationType;
}
public void setConversationType(int conversationType) {
this.conversationType = conversationType;
}
public String getTarget() {
return target;
}
public void setTarget(String target) {
this.target = target;
}
public int getLine() {
return line;
}
public void setLine(int line) {
this.line = line;
}
}
@@ -5,6 +5,9 @@ public class InputGetToken {
private String clientId;
private Integer platform;
public InputGetToken() {
}
public InputGetToken(String userId, String clientId, int platform) {
this.userId = userId;
this.clientId = clientId;
@@ -13,6 +13,9 @@ public class InputGetUserInfo {
private String name;
private String mobile;
public InputGetUserInfo() {
}
public InputGetUserInfo(String userId, String name, String mobile) {
this.userId = userId;
this.name = name;
@@ -13,6 +13,9 @@ public class InputOutputUserBlockStatus {
private String userId;
private int status;
public InputOutputUserBlockStatus() {
}
public InputOutputUserBlockStatus(String userId, int status) {
this.userId = userId;
this.status = status;
@@ -8,14 +8,14 @@
package cn.wildfirechat.pojos;
public class InputVerifyApplicationUser {
private String token;
public class InputRobotId {
private String robotId;
public String getToken() {
return token;
public String getRobotId() {
return robotId;
}
public void setToken(String token) {
this.token = token;
public void setRobotId(String robotId) {
this.robotId = robotId;
}
}
@@ -0,0 +1,48 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package cn.wildfirechat.pojos;
public class InputSubscribeChannel {
private String channelId;
private String userId;
private int subscribe; //1,订阅;0,取消订阅
public InputSubscribeChannel() {
}
public InputSubscribeChannel(String channelId, String userId, int subscribe) {
this.channelId = channelId;
this.userId = userId;
this.subscribe = subscribe;
}
public String getChannelId() {
return channelId;
}
public void setChannelId(String channelId) {
this.channelId = channelId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public int getSubscribe() {
return subscribe;
}
public void setSubscribe(int subscribe) {
this.subscribe = subscribe;
}
}
@@ -0,0 +1,6 @@
package cn.wildfirechat.pojos;
public class InputUserConversation {
public String userId;
public Conversation conversation;
}
@@ -11,6 +11,13 @@ package cn.wildfirechat.pojos;
public class InputUserId {
private String userId;
public InputUserId() {
}
public InputUserId(String userId) {
this.userId = userId;
}
public String getUserId() {
return userId;
}
@@ -0,0 +1,57 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package cn.wildfirechat.pojos;
public class OutputApplicationConfigData {
private String appId;
private int appType;
private long timestamp;
private String nonceStr;
private String signature;
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public int getAppType() {
return appType;
}
public void setAppType(int appType) {
this.appType = appType;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public String getNonceStr() {
return nonceStr;
}
public void setNonceStr(String nonceStr) {
this.nonceStr = nonceStr;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
}
@@ -0,0 +1,39 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package cn.wildfirechat.pojos;
public class OutputApplicationUserInfo {
private String userId;
private String displayName;
private String portraitUrl;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getPortraitUrl() {
return portraitUrl;
}
public void setPortraitUrl(String portraitUrl) {
this.portraitUrl = portraitUrl;
}
}
@@ -0,0 +1,21 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package cn.wildfirechat.pojos;
import cn.wildfirechat.proto.WFCMessage;
import io.netty.util.internal.StringUtil;
import java.util.ArrayList;
import java.util.List;
public class OutputBooleanValue {
public boolean value;
}
@@ -0,0 +1,40 @@
/*
* This file is part of the Wildfire Chat package.
* (c) Heavyrain2012 <heavyrain.lee@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
package cn.wildfirechat.pojos;
import java.util.List;
public class OutputClient {
private int platform;
private String clientId;
public OutputClient() {
}
public OutputClient(int platform, String clientId) {
this.platform = platform;
this.clientId = clientId;
}
public int getPlatform() {
return platform;
}
public void setPlatform(int platform) {
this.platform = platform;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
}
@@ -13,6 +13,9 @@ public class OutputCreateDevice {
private String token;
private String secret;
public OutputCreateDevice() {
}
public OutputCreateDevice(String userId, String token, String secret) {
this.deviceId = userId;
this.token = token;
@@ -12,6 +12,9 @@ public class OutputCreateRobot {
private String userId;
private String secret;
public OutputCreateRobot() {
}
public OutputCreateRobot(String userId, String secret) {
this.userId = userId;
this.secret = secret;
@@ -12,6 +12,9 @@ public class OutputCreateUser {
private String userId;
private String name;
public OutputCreateUser() {
}
public OutputCreateUser(String userId, String name) {
this.userId = userId;
this.name = name;
@@ -20,6 +20,9 @@ public class OutputDevice {
private List<String> owners;
private String extra;
public OutputDevice() {
}
public OutputDevice(String deviceId, String token, String secret) {
this.deviceId = deviceId;
this.token = token;
@@ -10,8 +10,69 @@ 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 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> {
}
private String channelId;
private String name;
private String desc;
@@ -24,7 +85,7 @@ public class OutputGetChannelInfo {
private String callback;
private int automatic;
private String secret;
public List<OutputMenu> menus;
public String getChannelId() {
return channelId;
@@ -136,6 +197,13 @@ public class OutputGetChannelInfo {
out.status = channelInfo.getStatus();;
out.updateDt = channelInfo.getUpdateDt();
out.secret = channelInfo.getSecret();
if (channelInfo.getMenuCount() > 0) {
out.menus = new ArrayList<>();
for (WFCMessage.ChannelMenu channelMenuMenu : channelInfo.getMenuList()) {
out.menus.add(OutputMenu.fromPbInfo(channelMenuMenu));
}
}
return out;
}
}
@@ -14,6 +14,9 @@ public class OutputLoginData {
private String userId;
private String token;
public OutputLoginData() {
}
public OutputLoginData(String userId, String token) {
this.userId = userId;
this.token = token;
@@ -20,6 +20,7 @@ public class OutputMessageData {
private MessagePayload payload;
private List<String> toUsers;
private long timestamp;
private OutputClient client;
public String getSender() {
return sender;
@@ -69,7 +70,19 @@ public class OutputMessageData {
this.timestamp = timestamp;
}
public OutputClient getClient() {
return client;
}
public void setClient(OutputClient client) {
this.client = client;
}
public static OutputMessageData fromProtoMessage(WFCMessage.Message protoMessage) {
return fromProtoMessage(protoMessage, null);
}
public static OutputMessageData fromProtoMessage(WFCMessage.Message protoMessage, OutputClient fromClient) {
OutputMessageData data = new OutputMessageData();
data.messageId = protoMessage.getMessageId();
data.sender = protoMessage.getFromUser();
@@ -80,6 +93,7 @@ public class OutputMessageData {
data.payload = MessagePayload.fromProtoMessageContent(protoMessage.getContent());
data.timestamp = protoMessage.getServerTimestamp();
data.toUsers = protoMessage.getToList();
data.client = fromClient;
return data;
}
}
@@ -13,6 +13,9 @@ public class OutputNotifyChannelSubscribeStatus {
private String channelId;
private int status;
public OutputNotifyChannelSubscribeStatus() {
}
public OutputNotifyChannelSubscribeStatus(String userId, String channelId, boolean subscirbed) {
this.userId = userId;
this.channelId = channelId;
@@ -0,0 +1,184 @@
package cn.wildfirechat.pojos;
import cn.wildfirechat.proto.WFCMessage;
public class OutputRobot {
private String userId;
private String name;
private String password;
private String displayName;
private String portrait;
private int gender;
private String mobile;
private String email;
private String address;
private String company;
private String social;
private String extra;
private long updateDt;
private String owner;
private String secret;
private String callback;
private String robotExtra;
public String getSocial() {
return social;
}
public void setSocial(String social) {
this.social = social;
}
public long getUpdateDt() {
return updateDt;
}
public void setUpdateDt(long updateDt) {
this.updateDt = updateDt;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getPortrait() {
return portrait;
}
public void setPortrait(String portrait) {
this.portrait = portrait;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public String getExtra() {
return extra;
}
public void setExtra(String extra) {
this.extra = extra;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public String getCallback() {
return callback;
}
public void setCallback(String callback) {
this.callback = callback;
}
public String getRobotExtra() {
return robotExtra;
}
public void setRobotExtra(String robotExtra) {
this.robotExtra = robotExtra;
}
public void fromUser(WFCMessage.User user) {
userId = user.getUid();
name = user.getName();
displayName = user.getDisplayName();
portrait = user.getPortrait();
gender = user.getGender();
mobile = user.getMobile();
email = user.getEmail();
address = user.getAddress();
company = user.getCompany();
social = user.getSocial();
extra = user.getExtra();
updateDt = user.getUpdateDt();
}
public void fromRobot(WFCMessage.Robot robot, boolean withSecret) {
setOwner(robot.getOwner());
if(withSecret) {
setSecret(robot.getSecret());
}
setCallback(robot.getCallback());
setRobotExtra(robot.getExtra());
}
}

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