├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── CHANGELOG.md ├── Install.md ├── LICENSE ├── Other ├── Install.sh ├── Products │ └── Debug │ │ └── WeChatPlugin.framework │ │ ├── Headers │ │ └── WeChatPlugin.h │ │ ├── Modules │ │ └── module.modulemap │ │ ├── Resources │ │ ├── Base.lproj │ │ │ ├── TKAboutWindowController.nib │ │ │ └── TKRemoteControlWindowController.nib │ │ ├── Info.plist │ │ ├── TKAutoReplyWindowController.nib │ │ ├── TKDownloadWindowController.nib │ │ ├── TKRemoteControlCommands.plist │ │ ├── TKRemoteControlScript.scpt │ │ ├── en.lproj │ │ │ ├── Localizable.strings │ │ │ ├── TKAboutWindowController.nib │ │ │ └── about.rtfd │ │ │ │ └── TXT.rtf │ │ ├── zh-Hans.lproj │ │ │ ├── Localizable.strings │ │ │ ├── TKRemoteControlWindowController.nib │ │ │ └── about.rtfd │ │ │ │ └── TXT.rtf │ │ └── zh-Hant.lproj │ │ │ ├── Localizable.strings │ │ │ ├── TKAboutWindowController.nib │ │ │ ├── TKRemoteControlWindowController.nib │ │ │ └── about.rtfd │ │ │ └── TXT.rtf │ │ ├── Versions │ │ ├── A │ │ │ ├── Headers │ │ │ │ └── WeChatPlugin.h │ │ │ ├── Modules │ │ │ │ └── module.modulemap │ │ │ ├── Resources │ │ │ │ ├── Base.lproj │ │ │ │ │ ├── TKAboutWindowController.nib │ │ │ │ │ └── TKRemoteControlWindowController.nib │ │ │ │ ├── Info.plist │ │ │ │ ├── TKAutoReplyWindowController.nib │ │ │ │ ├── TKDownloadWindowController.nib │ │ │ │ ├── TKRemoteControlCommands.plist │ │ │ │ ├── TKRemoteControlScript.scpt │ │ │ │ ├── en.lproj │ │ │ │ │ ├── Localizable.strings │ │ │ │ │ ├── TKAboutWindowController.nib │ │ │ │ │ └── about.rtfd │ │ │ │ │ │ └── TXT.rtf │ │ │ │ ├── zh-Hans.lproj │ │ │ │ │ ├── Localizable.strings │ │ │ │ │ ├── TKRemoteControlWindowController.nib │ │ │ │ │ └── about.rtfd │ │ │ │ │ │ └── TXT.rtf │ │ │ │ └── zh-Hant.lproj │ │ │ │ │ ├── Localizable.strings │ │ │ │ │ ├── TKAboutWindowController.nib │ │ │ │ │ ├── TKRemoteControlWindowController.nib │ │ │ │ │ └── about.rtfd │ │ │ │ │ └── TXT.rtf │ │ │ └── WeChatPlugin │ │ └── Current │ │ │ ├── Headers │ │ │ └── WeChatPlugin.h │ │ │ ├── Modules │ │ │ └── module.modulemap │ │ │ ├── Resources │ │ │ ├── Base.lproj │ │ │ │ ├── TKAboutWindowController.nib │ │ │ │ └── TKRemoteControlWindowController.nib │ │ │ ├── Info.plist │ │ │ ├── TKAutoReplyWindowController.nib │ │ │ ├── TKDownloadWindowController.nib │ │ │ ├── TKRemoteControlCommands.plist │ │ │ ├── TKRemoteControlScript.scpt │ │ │ ├── en.lproj │ │ │ │ ├── Localizable.strings │ │ │ │ ├── TKAboutWindowController.nib │ │ │ │ └── about.rtfd │ │ │ │ │ └── TXT.rtf │ │ │ ├── zh-Hans.lproj │ │ │ │ ├── Localizable.strings │ │ │ │ ├── TKRemoteControlWindowController.nib │ │ │ │ └── about.rtfd │ │ │ │ │ └── TXT.rtf │ │ │ └── zh-Hant.lproj │ │ │ │ ├── Localizable.strings │ │ │ │ ├── TKAboutWindowController.nib │ │ │ │ ├── TKRemoteControlWindowController.nib │ │ │ │ └── about.rtfd │ │ │ │ └── TXT.rtf │ │ │ └── WeChatPlugin │ │ └── WeChatPlugin ├── ScreenShots │ ├── alfred_chat_log.gif │ ├── alfred_search.gif │ ├── auto_reply.png │ ├── emotion_copy_export.png │ ├── en │ │ ├── alfred.gif │ │ ├── auto_auth_and_new.gif │ │ ├── auto_reply.gif │ │ ├── emotion_copy_export.png │ │ ├── multiselect_and_stick_bottom_and_clear_empty.gif │ │ ├── prevent_recall.gif │ │ ├── quick_reply_and_make_read.gif │ │ ├── remote_control.gif │ │ └── wechatplugin.png │ ├── install_download.png │ ├── install_terminal.png │ ├── notification_quick_reply.gif │ ├── remote_control.png │ ├── session_empty_and_clean.gif │ ├── terminal_path.png │ ├── voice_remote_control.gif │ └── wechatplugin.png ├── Uninstall.sh ├── Update.sh ├── UpdateRemoteControlCommandsPlist.py └── insert_dylib ├── Podfile ├── Q&A.md ├── README.md ├── README_EN.md ├── WeChatPlugin.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── TK.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── WeChatPlugin.xcscheme │ └── xcschememanagement.plist ├── WeChatPlugin.xcworkspace ├── contents.xcworkspacedata ├── xcshareddata │ └── IDEWorkspaceChecks.plist └── xcuserdata │ └── TK.xcuserdatad │ ├── IDEFindNavigatorScopes.plist │ └── xcdebugger │ └── Breakpoints_v2.xcbkptlist └── WeChatPlugin ├── Info.plist ├── Sources ├── Common │ ├── Category │ │ ├── NSButton+Action.h │ │ ├── NSButton+Action.m │ │ ├── NSDate+Action.h │ │ ├── NSDate+Action.m │ │ ├── NSMenu+Action.h │ │ ├── NSMenu+Action.m │ │ ├── NSMenuItem+Action.h │ │ ├── NSMenuItem+Action.m │ │ ├── NSString+Action.h │ │ ├── NSString+Action.m │ │ ├── NSTextField+Action.h │ │ ├── NSTextField+Action.m │ │ ├── NSView+Action.h │ │ ├── NSView+Action.m │ │ ├── NSWindowController+Action.h │ │ └── NSWindowController+Action.m │ ├── Macro │ │ ├── ColorConstant.h │ │ ├── DefineConstant.h │ │ └── NotifyConstant.h │ └── TKPrefixHeader.pch ├── Config │ ├── TKWeChatPluginConfig.h │ └── TKWeChatPluginConfig.m ├── Hook │ ├── MMChatsTableCellView+hook.h │ ├── MMChatsTableCellView+hook.m │ ├── MMStickerMessageCellView+hook.h │ ├── MMStickerMessageCellView+hook.m │ ├── WeChat+hook.h │ └── WeChat+hook.m ├── Managers │ ├── TKAssistantMenuManager.h │ ├── TKAssistantMenuManager.m │ ├── TKCacheManager.h │ ├── TKCacheManager.m │ ├── TKHTTPManager.h │ ├── TKHTTPManager.m │ ├── TKMessageManager.h │ ├── TKMessageManager.m │ ├── TKRemoteControlCommands.plist │ ├── TKRemoteControlManager.h │ ├── TKRemoteControlManager.m │ ├── TKVersionManager.h │ ├── TKVersionManager.m │ ├── TKWebServerManager.h │ └── TKWebServerManager.m ├── Models │ ├── TKAutoReplyModel.h │ ├── TKAutoReplyModel.m │ ├── TKBaseModel.h │ ├── TKBaseModel.m │ ├── TKIgnoreSessonModel.h │ ├── TKIgnoreSessonModel.m │ ├── TKRemoteControlModel.h │ └── TKRemoteControlModel.m ├── Utils │ ├── TKHelper.h │ ├── TKHelper.m │ ├── TKUtility.h │ └── TKUtility.m ├── Vendor │ ├── fishhook.c │ └── fishhook.h ├── Views │ ├── AutoReply │ │ ├── TKAutoReplyCell.h │ │ ├── TKAutoReplyCell.m │ │ ├── TKAutoReplyContentView.h │ │ └── TKAutoReplyContentView.m │ └── RemoteControl │ │ ├── TKRemoteControlCell.h │ │ └── TKRemoteControlCell.m └── WindowControllers │ ├── About │ ├── Base.lproj │ │ └── TKAboutWindowController.xib │ ├── TKAboutWindowController.h │ ├── TKAboutWindowController.m │ ├── en.lproj │ │ └── TKAboutWindowController.xib │ └── zh-Hant.lproj │ │ └── TKAboutWindowController.xib │ ├── AutoReply │ ├── TKAutoReplyWindowController.h │ ├── TKAutoReplyWindowController.m │ └── TKAutoReplyWindowController.xib │ ├── Download │ ├── TKDownloadWindowController.h │ ├── TKDownloadWindowController.m │ └── TKDownloadWindowController.xib │ └── RemoteControl │ ├── Base.lproj │ └── TKRemoteControlWindowController.xib │ ├── TKRemoteControlWindowController.h │ ├── TKRemoteControlWindowController.m │ ├── zh-Hans.lproj │ └── TKRemoteControlWindowController.xib │ └── zh-Hant.lproj │ └── TKRemoteControlWindowController.xib ├── TKRemoteControlScript.scpt ├── WeChatPlugin.h ├── en.lproj ├── Localizable.strings └── about.rtfd │ └── TXT.rtf ├── main.mm ├── zh-Hans.lproj ├── Localizable.strings └── about.rtfd │ └── TXT.rtf └── zh-Hant.lproj ├── Localizable.strings └── about.rtfd └── TXT.rtf /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 12 | 13 | ### 问题描述 14 | 15 | 16 | ### 版本 17 | 18 | * MacOS Version: 19 | * WeChat Version: 20 | * WeChatPlugin Version: 21 | 22 | ### 日志 23 | 24 | 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | .DS_Store 4 | *.xcuserstate 5 | 6 | # CocoaPods 7 | # 8 | Pods/ 9 | Podfile.lock 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 更新日志 2 | 3 | ### [v1.7.5 (2019-01-13)](https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.7.5) 4 | 5 | - 适配 2.3.22 6 | - 新增禁止微信检测更新开关 7 | - 优化 XML解析(在此感谢 @wangliangliang2 提醒) 8 | 9 | ###[v1.7.3 (2018-10-23)](https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.7.3) 10 | 11 | - 适配2.3.19 12 | - 菜单栏新增 alfred 开关 13 | - 更改更新弹窗逻辑 14 | - 新增自带浏览器浏览开关 15 | 16 | ### [v1.7.1 (2018-07-24)](https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.7.1) 17 | 18 | * 适配微信 Version. 2.3.17 19 | * 新增 alfred 搜索最近聊天列表 20 | * 新增 alfred 查看用户聊天记录 21 | 22 | ### [v1.7 (2018-05-12)](https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.7) 23 | 24 | * 新增不同账户设置不同的自动回复&远程控制 25 | * 自动回复新增总开关&指定联系人 26 | * 远程控制新增控制小助手配置 27 | * 新增一键已读 28 | * 新增一键清除空回话 29 | * 新增国际化(支持英、简、繁) 30 | * 新增关于小助手 31 | * 新增在线更新小助手 32 | * 去除微信url转链处理(从此直接打开抖音链接🌝 33 | * 修复无法免认证登录&多开等bug 34 | 35 | ### [v1.6.1 (2018-04-07)](https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.6.1) 36 | 37 | * 自动回复新增延迟回复 38 | * 调整置顶模式快捷键 39 | * 修复bug & 优化代码 40 | * 更新 README.md 文档 41 | 42 | ### [v1.6 (2018-03-18)](https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.6) 43 | 44 | * 新增 Alfred 快捷发送消息 & 打开聊天窗口 45 | 46 | ### [v1.5.1 (2018-03-03)](https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.5.1) 47 | 48 | * 新增语音远程控制 mac 49 | * 修复快捷回复后消息未读数未更新的问题 50 | * 优化防撤回提醒 (显示撤回人昵称 & 消息类型) 51 | 52 | ### [v1.5.0 (2018-02-24)](https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.5.0) 53 | 54 | * 优化防撤回提醒 55 | * 新增自动登录开关 56 | * 新增小助手检测更新 57 | * 新增通知中心快捷回复 58 | * 新增表情包复制 & 存储 59 | * 自动回复 & 远程控制设置存储到本地 60 | 61 | ### [v1.4.0 (2017-10-11)](https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.4.0) 62 | 63 | * 新增微信窗口置顶 64 | * 新增最近联系人多选删除 65 | * 新增远程控制信息回调 66 | * 新增手机端获取指令信息 67 | 68 | ### [v1.3.0 (2017-09-17)](https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.3.0) 69 | 70 | * 新增最近联系人置底功能 71 | * 新增免认证登录 72 | 73 | ### [v1.2.0 (2017-09-11)](https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.2.0) 74 | 75 | * 自动回复新增 正则匹配 & 私聊开关 76 | * 修复聊天记录消失 & `~/Documents` 生成MMappedKV、JietuSDKStat.plist 文件 77 | 78 | 79 | ### [v1.1.0 (2017-08-23)](https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.1.0) 80 | 81 | * 重构 自动回复,实现多回复 82 | * 优化 代码结构 83 | 84 | ### [v1.0.1 (2017-08-18)](https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.0.1) 85 | 86 | * 修复 部分防撤回提示乱码的bug 87 | * 新增 Install.sh & Uninstall.sh 88 | 89 | ### [v1.0.0 (2017-08-09)](https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.0.0) 90 | 91 | * 新增 远程控制 92 | * 新增 微信多开 93 | * 优化 消息防撤回 94 | * 优化 自动回复 95 | 96 | -------------------------------------------------------------------------------- /Install.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Install 4 | 5 | **第一次安装需要输入密码,仅是为了获取写入微信文件夹的权限** 6 | 7 | **0. 懒癌版安装&升级** 8 | 9 | 打开`应用程序-实用工具-Terminal(终端)`,执行下面的命令安装 [Oh My WeChat](https://github.com/lmk123/oh-my-wechat): 10 | 11 | ```sh 12 | curl -o- -L https://raw.githubusercontent.com/lmk123/oh-my-wechat/master/install.sh | bash -s 13 | ``` 14 | 15 | 然后运行 `omw` 即可。 16 | 17 | > 可以访问 [Oh My WeChat 的项目主页](https://github.com/lmk123/oh-my-wechat#oh-my-wechat)查看更多用法。 18 | 19 | **1. 普通安装** 20 | 21 | * 点击`clone or download`按钮下载 WeChatPlugin 并解压 22 | 23 | ![clone or download](./Other/ScreenShots/install_download.png) 24 | 25 | * 从`应用程序-实用工具`中打开Terminal(终端) 26 | 27 | ![terminal](./Other/ScreenShots/terminal_path.png) 28 | 29 | * 拖动解压后`Install.sh` 文件到终端中回车即可. 30 | 31 | ![terminal](./Other/ScreenShots/install_terminal.png) 32 | 33 | **2. 若想修改源码&重编译(需要安装Cocoapods)** 34 | 35 | * 先更改微信的 owner 以获取写入微信文件夹的权限,否则会出现类似**Permission denied**的错误。 36 | 37 | `sudo chown -R $(whoami) /Applications/WeChat.app` 38 | 39 | ![Permission denied.png](http://upload-images.jianshu.io/upload_images/965383-11e4480553ba086e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 40 | 41 | * 下载 WeChatPlugin, 进行`Pod install`。 42 | * 用Xcode打开,编辑 Scheme,在 Debug 模式下启动 WeChat。 43 | ![](http://upload-images.jianshu.io/upload_images/965383-26dbb068acb8998f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 44 | ![edit scheme](http://upload-images.jianshu.io/upload_images/965383-7fbd4dc6e8d161dc.gif?imageMogr2/auto-orient/strip) 45 | * 之后 Run (`command + R`)即可启动微信,此时插件注入完成。 46 | 47 | * 若 Error,提示找不到 Framework,先进行 Build。 48 | * 若Error, 需要配置环境,请参考[我的博客](http://www.tkkk.fun/2017/04/21/macOS%E9%80%86%E5%90%91-%E5%BE%AE%E4%BF%A1%E5%B0%8F%E5%8A%A9%E6%89%8B/)。 49 | 50 | ## 卸载 51 | 52 | * 打开Terminal(终端),拖动解压后`Uninstall.sh` 文件到 Terminal 回车即可。 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 TK 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Other/Install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | wechat_path="/Applications/WeChat.app" 4 | 5 | if [ ! -d "$wechat_path" ] 6 | then 7 | wechat_path="/Applications/微信.app" 8 | if [ ! -d "$wechat_path" ] 9 | then 10 | echo -e "\n\n应用程序文件夹中未发现微信,请检查微信是否有重命名或者移动路径位置" 11 | exit 12 | fi 13 | fi 14 | 15 | app_name="WeChat" 16 | shell_path="$(dirname "$0")" 17 | framework_name="WeChatPlugin" 18 | app_bundle_path="${wechat_path}/Contents/MacOS" 19 | app_executable_path="${app_bundle_path}/${app_name}" 20 | app_executable_backup_path="${app_executable_path}_backup" 21 | framework_path="${app_bundle_path}/${framework_name}.framework" 22 | 23 | 24 | # 对 WeChat 赋予权限 25 | if [ ! -w "$wechat_path" ] 26 | then 27 | echo -e "\n\n为了将小助手写入微信, 请输入密码 : " 28 | sudo chown -R $(whoami) "$wechat_path" 29 | fi 30 | 31 | # 判断是否已经存在备份文件 或者 是否强制覆盖安装 32 | if [ ! -f "$app_executable_backup_path" ] || [ -n "$1" -a "$1" = "--force" ] 33 | then 34 | # 备份 WeChat 原始可执行文件 35 | cp "$app_executable_path" "$app_executable_backup_path" 36 | result="y" 37 | else 38 | read -t 150 -p "已安装微信小助手,是否覆盖?[y/n]:" result 39 | fi 40 | 41 | if [[ "$result" == 'y' ]]; then 42 | cp -r "${shell_path}/Products/Debug/${framework_name}.framework" ${app_bundle_path} 43 | ${shell_path}/insert_dylib --all-yes "${framework_path}/${framework_name}" "$app_executable_backup_path" "$app_executable_path" 44 | ${shell_path}/UpdateRemoteControlCommandsPlist.py 45 | fi 46 | -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module WeChatPlugin { 2 | umbrella header "WeChatPlugin.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Resources/Base.lproj/TKAboutWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Resources/Base.lproj/TKAboutWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Resources/Base.lproj/TKRemoteControlWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Resources/Base.lproj/TKRemoteControlWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 18A391 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | WeChatPlugin 11 | CFBundleIdentifier 12 | tk.WeChatPlugin 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | WeChatPlugin 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 1.7.5 21 | CFBundleSupportedPlatforms 22 | 23 | MacOSX 24 | 25 | CFBundleVersion 26 | 1 27 | DTCompiler 28 | com.apple.compilers.llvm.clang.1_0 29 | DTPlatformBuild 30 | 10B61 31 | DTPlatformVersion 32 | GM 33 | DTSDKBuild 34 | 18B71 35 | DTSDKName 36 | macosx10.14 37 | DTXcode 38 | 1010 39 | DTXcodeBuild 40 | 10B61 41 | NSHumanReadableCopyright 42 | Copyright © 2017年 tk. All rights reserved. 43 | showUpdateWindow 44 | 45 | versionInfo 46 | v1.7.5(2019-01-13):\n👉🏻 适配微信 Version. 2.3.22\n👉🏼 菜单栏新增是否允许微信启动时检测更新(非AppStore版本)\n👉🏽 优化 XML 解析\n\n\n\nv1.7.3 (2018-10-22):\n👉🏻 适配微信 Version. 2.3.19\n👉🏼 修复安全漏洞(请务必更新,若有安装QQ插件也需要更新)\n👉🏽 菜单栏-关于小助手-新增 alfred 开关(若不使用 aflred 可关闭) \n\nv1.7.1 (2018-07-24):\n👉🏻 适配微信 Version. 2.3.17\n👉🏼 新增 alfred 搜索最近聊天列表\n👉🏽 新增 alfred 查看用户聊天记录\n (需更新wechat-alfred-workflow)\n\nv1.7 (2018-05-12):\n👉🏻 新增不同账户设置不同的自动回复&远程控制\n👉🏼 自动回复新增总开关&指定联系人\n👉🏽 远程控制新增控制小助手配置\n👉🏾 新增一键已读\n👉 新增一键清除空回话\n👉🏻 新增国际化(支持英、简、繁)\n👉🏼 新增关于小助手\n👉🏽 新增在线更新小助手 \n👉🏾 去除微信url转链处理(从此直接打开抖音链接🌝 \n👉🏿 修复无法免认证登录&多开等bug \n 47 | 48 | 49 | -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Resources/TKAutoReplyWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Resources/TKAutoReplyWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Resources/TKDownloadWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Resources/TKDownloadWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Resources/TKRemoteControlScript.scpt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Resources/TKRemoteControlScript.scpt -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Resources/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Resources/en.lproj/Localizable.strings -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Resources/en.lproj/TKAboutWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Resources/en.lproj/TKAboutWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Resources/en.lproj/about.rtfd/TXT.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg936\cocoartf1671 2 | {\fonttbl\f0\fnil\fcharset0 HelveticaNeue-Light;\f1\fnil\fcharset0 HelveticaNeue;\f2\fnil\fcharset0 HelveticaNeue-Bold; 3 | \f3\fnil\fcharset134 PingFangSC-Regular;} 4 | {\colortbl;\red255\green255\blue255;\red38\green38\blue38;\red32\green124\blue169;} 5 | {\*\expandedcolortbl;;\cssrgb\c20000\c20000\c20000;\cssrgb\c14510\c56078\c72157;} 6 | {\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1}} 7 | {\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}} 8 | \margl1440\margr1440\vieww13760\viewh11300\viewkind0 9 | \hyphauto1\hyphfactor90 10 | \deftab720 11 | \pard\pardeftab720\qc\partightenfactor0 12 | 13 | \f0\fs34 \cf2 \expnd0\expndtw0\kerning0 14 | Github: {\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS"}}{\fldrslt \cf3 WeChatPlugin-MacOS}}\ 15 | Email: {\field{\*\fldinst{HYPERLINK "mailto:tkk.ioser@gmail.com"}}{\fldrslt \cf3 tkk.ioser@gmail.com}} 16 | \f1 \ 17 | \pard\pardeftab720\sl288\slmult1\qc\partightenfactor0 18 | 19 | \fs28 \cf2 \ 20 | \pard\pardeftab720\partightenfactor0 21 | 22 | \f2\b\fs34 \cf2 Feature 23 | \fs47\fsmilli23660 \ 24 | \pard\tx220\tx720\pardeftab720\li720\fi-720\sl264\slmult1\partightenfactor0 25 | \ls1\ilvl0 26 | \f0\b0\fs30 \cf2 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 27 | Message auto reply\ 28 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 29 | Prevent message recall\ 30 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 31 | Remote control(support voice control)\ 32 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 33 | Multiple WeChat\ 34 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 35 | Auto Auth Login\ 36 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 37 | Session Sticky Bottom\ 38 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 39 | Windows Sticky Top\ 40 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 41 | Session multiple delete\ 42 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 43 | Auto Login Switch\ 44 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 45 | Quick reply to notifications\ 46 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 47 | Copy or Export Sticker\ 48 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 49 | Update plugin\ 50 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 51 | Reply or Open session by Alfred 52 | \f3\fs32 \ 53 | } -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Resources/zh-Hans.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Resources/zh-Hans.lproj/Localizable.strings -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Resources/zh-Hans.lproj/TKRemoteControlWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Resources/zh-Hans.lproj/TKRemoteControlWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Resources/zh-Hant.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Resources/zh-Hant.lproj/Localizable.strings -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Resources/zh-Hant.lproj/TKAboutWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Resources/zh-Hant.lproj/TKAboutWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Resources/zh-Hant.lproj/TKRemoteControlWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Resources/zh-Hant.lproj/TKRemoteControlWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Resources/zh-Hant.lproj/about.rtfd/TXT.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg936\cocoartf1671 2 | {\fonttbl\f0\fnil\fcharset0 HelveticaNeue-Light;\f1\fnil\fcharset0 HelveticaNeue;\f2\fnil\fcharset134 PingFangSC-Semibold; 3 | \f3\fnil\fcharset0 HelveticaNeue-Bold;\f4\fnil\fcharset134 PingFangSC-Light;} 4 | {\colortbl;\red255\green255\blue255;\red38\green38\blue38;\red32\green124\blue169;} 5 | {\*\expandedcolortbl;;\cssrgb\c20000\c20000\c20000;\cssrgb\c14510\c56078\c72157;} 6 | {\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1} 7 | {\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid101\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid2}} 8 | {\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}} 9 | \margl1440\margr1440\vieww13760\viewh11300\viewkind0 10 | \hyphauto1\hyphfactor90 11 | \deftab720 12 | \pard\pardeftab720\qc\partightenfactor0 13 | 14 | \f0\fs36\fsmilli18200 \cf2 \expnd0\expndtw0\kerning0 15 | Github: {\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS"}}{\fldrslt \cf3 WeChatPlugin-MacOS}}\ 16 | Email: {\field{\*\fldinst{HYPERLINK "mailto:tkk.ioser@gmail.com"}}{\fldrslt \cf3 tkk.ioser@gmail.com}} 17 | \f1\fs32 \ 18 | \pard\pardeftab720\sl288\slmult1\qc\partightenfactor0 19 | 20 | \fs28 \cf2 \ 21 | \pard\pardeftab720\partightenfactor0 22 | 23 | \f2\b\fs36 \cf2 \'b9\'a6\'c4\'dc 24 | \f3\fs47\fsmilli23660 \cf2 \ 25 | \pard\tx220\tx720\pardeftab720\li720\fi-720\partightenfactor0 26 | \ls1\ilvl0 27 | \f0\b0\fs32 \cf2 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 28 | \f4 \expnd0\expndtw0\kerning0 29 | \'cf\'fb\'cf\'a2\'d7\'d4\'84\'d3\'bb\'d8\'8f\'cd 30 | \f0 \ 31 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 32 | \f4 \expnd0\expndtw0\kerning0 33 | \'cf\'fb\'cf\'a2\'b7\'c0\'b3\'b7\'bb\'d8 34 | \f0 \ 35 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 36 | \f4 \expnd0\expndtw0\kerning0 37 | \'df\'68\'b3\'cc\'bf\'d8\'d6\'c6 38 | \f0 ( 39 | \f4 \'d2\'d1\'d6\'a7\'b3\'d6\'d5\'5a\'d2\'f4 40 | \f0 )\ 41 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 42 | \f4 \expnd0\expndtw0\kerning0 43 | \'ce\'a2\'d0\'c5\'b6\'e0\'e9\'5f 44 | \f0 \ 45 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 46 | \f4 \expnd0\expndtw0\kerning0 47 | \'b5\'da\'b6\'fe\'b4\'ce\'b5\'c7\'e4\'9b\'c3\'e2\'d5\'4a\'d7\'43 48 | \f0 \ 49 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 50 | \f4 \expnd0\expndtw0\kerning0 51 | \'c1\'c4\'cc\'ec\'d6\'c3\'b5\'d7\'b9\'a6\'c4\'dc 52 | \f0 ( 53 | \f4 \strike \strikec2 \'ee\'90\'cb\'c6\'d6\'c3\'ed\'94 54 | \f0 \strike0\striked0 )\ 55 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 56 | \f4 \expnd0\expndtw0\kerning0 57 | \'ce\'a2\'d0\'c5\'b4\'b0\'bf\'da\'d6\'c3\'ed\'94 58 | \f0 \ 59 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 60 | \f4 \expnd0\expndtw0\kerning0 61 | \'95\'fe\'d4\'92\'b6\'e0\'df\'78\'84\'68\'b3\'fd 62 | \f0 \ 63 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 64 | \f4 \expnd0\expndtw0\kerning0 65 | \'d7\'d4\'84\'d3\'b5\'c7\'e4\'9b\'e9\'5f\'ea\'50 66 | \f0 \ 67 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 68 | \f4 \expnd0\expndtw0\kerning0 69 | \'cd\'a8\'d6\'aa\'d6\'d0\'d0\'c4\'bf\'ec\'bd\'dd\'bb\'d8\'8f\'cd 70 | \f0 \ 71 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 72 | \f4 \expnd0\expndtw0\kerning0 73 | \'c1\'c4\'cc\'ec\'b4\'b0\'bf\'da\'b1\'ed\'c7\'e9\'b0\'fc\'8f\'cd\'d6\'c6 74 | \f0 & 75 | \f4 \'b4\'e6\'83\'a6 76 | \f0 \ 77 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 78 | \f4 \expnd0\expndtw0\kerning0 79 | \'d0\'a1\'d6\'fa\'ca\'d6\'99\'7a\'9c\'79\'b8\'fc\'d0\'c2\'cc\'e1\'d0\'d1 80 | \f0 \ 81 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 82 | alfred 83 | \f4 \'bf\'ec\'bd\'dd\'b0\'6c\'cb\'cd\'cf\'fb\'cf\'a2 84 | \f0 & 85 | \f4 \'b4\'f2\'e9\'5f\'b4\'b0\'bf\'da 86 | \f0 \ 87 | \pard\tx566\pardeftab720\partightenfactor0 88 | 89 | \fs36\fsmilli18200 \cf2 \ 90 | \pard\pardeftab720\partightenfactor0 91 | 92 | \f2\b\fs36 \cf2 \'b8\'fc\'d0\'c2\'c8\'d5\'d5\'49 93 | \f3\fs47\fsmilli23660 \cf2 \ 94 | \pard\tx220\tx720\pardeftab720\li720\fi-720\sl264\slmult1\partightenfactor0 95 | \ls2\ilvl0 96 | \f0\b0\fs32 \cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.6.1"}}{\fldrslt 97 | \f4 \expnd0\expndtw0\kerning0 98 | \'d0\'c2\'d4\'f6\'d7\'d4\'84\'d3\'bb\'d8\'8f\'cd\'d1\'d3\'df\'74 99 | \f0 & 100 | \f4 \'d0\'de\'b8\'c4\'d6\'c3\'ed\'94\'b4\'b0\'bf\'da\'bf\'ec\'bd\'dd 101 | \f0 (2018-04-07)}}\cf2 \expnd0\expndtw0\kerning0 102 | \ 103 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.6"}}{\fldrslt 104 | \f4 \expnd0\expndtw0\kerning0 105 | \'d0\'c2\'d4\'f6 106 | \f0 Alfred 107 | \f4 \'bf\'ec\'bd\'dd\'b0\'6c\'cb\'cd\'cf\'fb\'cf\'a2 108 | \f0 & 109 | \f4 \'b4\'f2\'e9\'5f\'c1\'c4\'cc\'ec\'b4\'b0\'bf\'da 110 | \f0 (2018-03-18)}}\cf2 \expnd0\expndtw0\kerning0 111 | \ 112 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.5.1"}}{\fldrslt 113 | \f4 \expnd0\expndtw0\kerning0 114 | \'d0\'c2\'d4\'f6\'d5\'5a\'d2\'f4\'df\'68\'b3\'cc\'bf\'d8\'d6\'c6 115 | \f0 mac & 116 | \f4 \'83\'9e\'bb\'af\'b3\'b7\'bb\'d8\'cf\'fb\'cf\'a2\'a1\'a2\'bf\'ec\'bd\'dd\'bb\'d8\'8f\'cd 117 | \f0 (2018-03-03)}}\cf2 \expnd0\expndtw0\kerning0 118 | \ 119 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.5.0"}}{\fldrslt 120 | \f4 \expnd0\expndtw0\kerning0 121 | \'d0\'c2\'d4\'f6\'d0\'a1\'d6\'fa\'ca\'d6\'99\'7a\'9c\'79\'b8\'fc\'d0\'c2 122 | \f0 & 123 | \f4 \'b1\'ed\'c7\'e9\'b0\'fc\'8f\'cd\'d6\'c6\'b4\'e6\'83\'a6\'b5\'c8\'b5\'c8 124 | \f0 (2018-02-24)}}\cf2 \expnd0\expndtw0\kerning0 125 | \ 126 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.4.0"}}{\fldrslt 127 | \f4 \expnd0\expndtw0\kerning0 128 | \'d0\'c2\'d4\'f6\'b4\'b0\'bf\'da\'d6\'c3\'ed\'94 129 | \f0 & 130 | \f4 \'b6\'e0\'df\'78\'84\'68\'b3\'fd\'b5\'c8\'b5\'c8 131 | \f0 (2017-10-11)}}\cf2 \expnd0\expndtw0\kerning0 132 | \ 133 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.3.0"}}{\fldrslt 134 | \f4 \expnd0\expndtw0\kerning0 135 | \'d0\'c2\'d4\'f6\'d6\'c3\'b5\'d7 136 | \f0 & 137 | \f4 \'c3\'e2\'d5\'4a\'d7\'43 138 | \f0 (2017-09-17)}}\cf2 \expnd0\expndtw0\kerning0 139 | \ 140 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.2.0"}}{\fldrslt 141 | \f4 \expnd0\expndtw0\kerning0 142 | \'d0\'de\'8f\'cd\'c1\'c4\'cc\'ec\'d3\'9b\'e4\'9b\'cf\'fb\'ca\'a7\'b5\'c4 143 | \f0 bug (2017-09-11)}}\cf2 \expnd0\expndtw0\kerning0 144 | \ 145 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.1.0"}}{\fldrslt 146 | \f4 \expnd0\expndtw0\kerning0 147 | \'d6\'d8\'98\'8b\'d7\'d4\'84\'d3\'bb\'d8\'8f\'cd\'a3\'ac\'8c\'8d\'ac\'46\'b6\'e0\'bb\'d8\'8f\'cd 148 | \f0 (2017-08-23)}}\cf2 \expnd0\expndtw0\kerning0 149 | \ 150 | \pard\pardeftab720\sl264\slmult1\partightenfactor0 151 | 152 | \f2\b \cf2 \'d4\'94\'bc\'9a\'83\'c8\'c8\'dd\'d5\'88\'b2\'e9\'bf\'b4{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/blob/master/CHANGELOG.md"}}{\fldrslt 153 | \f0\b0 \cf3 CHANGELOG}} 154 | \f0\b0\fs36\fsmilli18200 \cf2 \ 155 | } -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/A/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module WeChatPlugin { 2 | umbrella header "WeChatPlugin.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/Base.lproj/TKAboutWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/Base.lproj/TKAboutWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/Base.lproj/TKRemoteControlWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/Base.lproj/TKRemoteControlWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 18A391 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | WeChatPlugin 11 | CFBundleIdentifier 12 | tk.WeChatPlugin 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | WeChatPlugin 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 1.7.5 21 | CFBundleSupportedPlatforms 22 | 23 | MacOSX 24 | 25 | CFBundleVersion 26 | 1 27 | DTCompiler 28 | com.apple.compilers.llvm.clang.1_0 29 | DTPlatformBuild 30 | 10B61 31 | DTPlatformVersion 32 | GM 33 | DTSDKBuild 34 | 18B71 35 | DTSDKName 36 | macosx10.14 37 | DTXcode 38 | 1010 39 | DTXcodeBuild 40 | 10B61 41 | NSHumanReadableCopyright 42 | Copyright © 2017年 tk. All rights reserved. 43 | showUpdateWindow 44 | 45 | versionInfo 46 | v1.7.5(2019-01-13):\n👉🏻 适配微信 Version. 2.3.22\n👉🏼 菜单栏新增是否允许微信启动时检测更新(非AppStore版本)\n👉🏽 优化 XML 解析\n\n\n\nv1.7.3 (2018-10-22):\n👉🏻 适配微信 Version. 2.3.19\n👉🏼 修复安全漏洞(请务必更新,若有安装QQ插件也需要更新)\n👉🏽 菜单栏-关于小助手-新增 alfred 开关(若不使用 aflred 可关闭) \n\nv1.7.1 (2018-07-24):\n👉🏻 适配微信 Version. 2.3.17\n👉🏼 新增 alfred 搜索最近聊天列表\n👉🏽 新增 alfred 查看用户聊天记录\n (需更新wechat-alfred-workflow)\n\nv1.7 (2018-05-12):\n👉🏻 新增不同账户设置不同的自动回复&远程控制\n👉🏼 自动回复新增总开关&指定联系人\n👉🏽 远程控制新增控制小助手配置\n👉🏾 新增一键已读\n👉 新增一键清除空回话\n👉🏻 新增国际化(支持英、简、繁)\n👉🏼 新增关于小助手\n👉🏽 新增在线更新小助手 \n👉🏾 去除微信url转链处理(从此直接打开抖音链接🌝 \n👉🏿 修复无法免认证登录&多开等bug \n 47 | 48 | 49 | -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/TKAutoReplyWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/TKAutoReplyWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/TKDownloadWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/TKDownloadWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/TKRemoteControlScript.scpt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/TKRemoteControlScript.scpt -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/en.lproj/Localizable.strings -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/en.lproj/TKAboutWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/en.lproj/TKAboutWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/en.lproj/about.rtfd/TXT.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg936\cocoartf1671 2 | {\fonttbl\f0\fnil\fcharset0 HelveticaNeue-Light;\f1\fnil\fcharset0 HelveticaNeue;\f2\fnil\fcharset0 HelveticaNeue-Bold; 3 | \f3\fnil\fcharset134 PingFangSC-Regular;} 4 | {\colortbl;\red255\green255\blue255;\red38\green38\blue38;\red32\green124\blue169;} 5 | {\*\expandedcolortbl;;\cssrgb\c20000\c20000\c20000;\cssrgb\c14510\c56078\c72157;} 6 | {\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1}} 7 | {\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}} 8 | \margl1440\margr1440\vieww13760\viewh11300\viewkind0 9 | \hyphauto1\hyphfactor90 10 | \deftab720 11 | \pard\pardeftab720\qc\partightenfactor0 12 | 13 | \f0\fs34 \cf2 \expnd0\expndtw0\kerning0 14 | Github: {\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS"}}{\fldrslt \cf3 WeChatPlugin-MacOS}}\ 15 | Email: {\field{\*\fldinst{HYPERLINK "mailto:tkk.ioser@gmail.com"}}{\fldrslt \cf3 tkk.ioser@gmail.com}} 16 | \f1 \ 17 | \pard\pardeftab720\sl288\slmult1\qc\partightenfactor0 18 | 19 | \fs28 \cf2 \ 20 | \pard\pardeftab720\partightenfactor0 21 | 22 | \f2\b\fs34 \cf2 Feature 23 | \fs47\fsmilli23660 \ 24 | \pard\tx220\tx720\pardeftab720\li720\fi-720\sl264\slmult1\partightenfactor0 25 | \ls1\ilvl0 26 | \f0\b0\fs30 \cf2 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 27 | Message auto reply\ 28 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 29 | Prevent message recall\ 30 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 31 | Remote control(support voice control)\ 32 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 33 | Multiple WeChat\ 34 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 35 | Auto Auth Login\ 36 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 37 | Session Sticky Bottom\ 38 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 39 | Windows Sticky Top\ 40 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 41 | Session multiple delete\ 42 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 43 | Auto Login Switch\ 44 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 45 | Quick reply to notifications\ 46 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 47 | Copy or Export Sticker\ 48 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 49 | Update plugin\ 50 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 51 | Reply or Open session by Alfred 52 | \f3\fs32 \ 53 | } -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/zh-Hans.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/zh-Hans.lproj/Localizable.strings -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/zh-Hans.lproj/TKRemoteControlWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/zh-Hans.lproj/TKRemoteControlWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/zh-Hant.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/zh-Hant.lproj/Localizable.strings -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/zh-Hant.lproj/TKAboutWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/zh-Hant.lproj/TKAboutWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/zh-Hant.lproj/TKRemoteControlWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/zh-Hant.lproj/TKRemoteControlWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/A/Resources/zh-Hant.lproj/about.rtfd/TXT.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg936\cocoartf1671 2 | {\fonttbl\f0\fnil\fcharset0 HelveticaNeue-Light;\f1\fnil\fcharset0 HelveticaNeue;\f2\fnil\fcharset134 PingFangSC-Semibold; 3 | \f3\fnil\fcharset0 HelveticaNeue-Bold;\f4\fnil\fcharset134 PingFangSC-Light;} 4 | {\colortbl;\red255\green255\blue255;\red38\green38\blue38;\red32\green124\blue169;} 5 | {\*\expandedcolortbl;;\cssrgb\c20000\c20000\c20000;\cssrgb\c14510\c56078\c72157;} 6 | {\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1} 7 | {\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid101\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid2}} 8 | {\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}} 9 | \margl1440\margr1440\vieww13760\viewh11300\viewkind0 10 | \hyphauto1\hyphfactor90 11 | \deftab720 12 | \pard\pardeftab720\qc\partightenfactor0 13 | 14 | \f0\fs36\fsmilli18200 \cf2 \expnd0\expndtw0\kerning0 15 | Github: {\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS"}}{\fldrslt \cf3 WeChatPlugin-MacOS}}\ 16 | Email: {\field{\*\fldinst{HYPERLINK "mailto:tkk.ioser@gmail.com"}}{\fldrslt \cf3 tkk.ioser@gmail.com}} 17 | \f1\fs32 \ 18 | \pard\pardeftab720\sl288\slmult1\qc\partightenfactor0 19 | 20 | \fs28 \cf2 \ 21 | \pard\pardeftab720\partightenfactor0 22 | 23 | \f2\b\fs36 \cf2 \'b9\'a6\'c4\'dc 24 | \f3\fs47\fsmilli23660 \cf2 \ 25 | \pard\tx220\tx720\pardeftab720\li720\fi-720\partightenfactor0 26 | \ls1\ilvl0 27 | \f0\b0\fs32 \cf2 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 28 | \f4 \expnd0\expndtw0\kerning0 29 | \'cf\'fb\'cf\'a2\'d7\'d4\'84\'d3\'bb\'d8\'8f\'cd 30 | \f0 \ 31 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 32 | \f4 \expnd0\expndtw0\kerning0 33 | \'cf\'fb\'cf\'a2\'b7\'c0\'b3\'b7\'bb\'d8 34 | \f0 \ 35 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 36 | \f4 \expnd0\expndtw0\kerning0 37 | \'df\'68\'b3\'cc\'bf\'d8\'d6\'c6 38 | \f0 ( 39 | \f4 \'d2\'d1\'d6\'a7\'b3\'d6\'d5\'5a\'d2\'f4 40 | \f0 )\ 41 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 42 | \f4 \expnd0\expndtw0\kerning0 43 | \'ce\'a2\'d0\'c5\'b6\'e0\'e9\'5f 44 | \f0 \ 45 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 46 | \f4 \expnd0\expndtw0\kerning0 47 | \'b5\'da\'b6\'fe\'b4\'ce\'b5\'c7\'e4\'9b\'c3\'e2\'d5\'4a\'d7\'43 48 | \f0 \ 49 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 50 | \f4 \expnd0\expndtw0\kerning0 51 | \'c1\'c4\'cc\'ec\'d6\'c3\'b5\'d7\'b9\'a6\'c4\'dc 52 | \f0 ( 53 | \f4 \strike \strikec2 \'ee\'90\'cb\'c6\'d6\'c3\'ed\'94 54 | \f0 \strike0\striked0 )\ 55 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 56 | \f4 \expnd0\expndtw0\kerning0 57 | \'ce\'a2\'d0\'c5\'b4\'b0\'bf\'da\'d6\'c3\'ed\'94 58 | \f0 \ 59 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 60 | \f4 \expnd0\expndtw0\kerning0 61 | \'95\'fe\'d4\'92\'b6\'e0\'df\'78\'84\'68\'b3\'fd 62 | \f0 \ 63 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 64 | \f4 \expnd0\expndtw0\kerning0 65 | \'d7\'d4\'84\'d3\'b5\'c7\'e4\'9b\'e9\'5f\'ea\'50 66 | \f0 \ 67 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 68 | \f4 \expnd0\expndtw0\kerning0 69 | \'cd\'a8\'d6\'aa\'d6\'d0\'d0\'c4\'bf\'ec\'bd\'dd\'bb\'d8\'8f\'cd 70 | \f0 \ 71 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 72 | \f4 \expnd0\expndtw0\kerning0 73 | \'c1\'c4\'cc\'ec\'b4\'b0\'bf\'da\'b1\'ed\'c7\'e9\'b0\'fc\'8f\'cd\'d6\'c6 74 | \f0 & 75 | \f4 \'b4\'e6\'83\'a6 76 | \f0 \ 77 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 78 | \f4 \expnd0\expndtw0\kerning0 79 | \'d0\'a1\'d6\'fa\'ca\'d6\'99\'7a\'9c\'79\'b8\'fc\'d0\'c2\'cc\'e1\'d0\'d1 80 | \f0 \ 81 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 82 | alfred 83 | \f4 \'bf\'ec\'bd\'dd\'b0\'6c\'cb\'cd\'cf\'fb\'cf\'a2 84 | \f0 & 85 | \f4 \'b4\'f2\'e9\'5f\'b4\'b0\'bf\'da 86 | \f0 \ 87 | \pard\tx566\pardeftab720\partightenfactor0 88 | 89 | \fs36\fsmilli18200 \cf2 \ 90 | \pard\pardeftab720\partightenfactor0 91 | 92 | \f2\b\fs36 \cf2 \'b8\'fc\'d0\'c2\'c8\'d5\'d5\'49 93 | \f3\fs47\fsmilli23660 \cf2 \ 94 | \pard\tx220\tx720\pardeftab720\li720\fi-720\sl264\slmult1\partightenfactor0 95 | \ls2\ilvl0 96 | \f0\b0\fs32 \cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.6.1"}}{\fldrslt 97 | \f4 \expnd0\expndtw0\kerning0 98 | \'d0\'c2\'d4\'f6\'d7\'d4\'84\'d3\'bb\'d8\'8f\'cd\'d1\'d3\'df\'74 99 | \f0 & 100 | \f4 \'d0\'de\'b8\'c4\'d6\'c3\'ed\'94\'b4\'b0\'bf\'da\'bf\'ec\'bd\'dd 101 | \f0 (2018-04-07)}}\cf2 \expnd0\expndtw0\kerning0 102 | \ 103 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.6"}}{\fldrslt 104 | \f4 \expnd0\expndtw0\kerning0 105 | \'d0\'c2\'d4\'f6 106 | \f0 Alfred 107 | \f4 \'bf\'ec\'bd\'dd\'b0\'6c\'cb\'cd\'cf\'fb\'cf\'a2 108 | \f0 & 109 | \f4 \'b4\'f2\'e9\'5f\'c1\'c4\'cc\'ec\'b4\'b0\'bf\'da 110 | \f0 (2018-03-18)}}\cf2 \expnd0\expndtw0\kerning0 111 | \ 112 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.5.1"}}{\fldrslt 113 | \f4 \expnd0\expndtw0\kerning0 114 | \'d0\'c2\'d4\'f6\'d5\'5a\'d2\'f4\'df\'68\'b3\'cc\'bf\'d8\'d6\'c6 115 | \f0 mac & 116 | \f4 \'83\'9e\'bb\'af\'b3\'b7\'bb\'d8\'cf\'fb\'cf\'a2\'a1\'a2\'bf\'ec\'bd\'dd\'bb\'d8\'8f\'cd 117 | \f0 (2018-03-03)}}\cf2 \expnd0\expndtw0\kerning0 118 | \ 119 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.5.0"}}{\fldrslt 120 | \f4 \expnd0\expndtw0\kerning0 121 | \'d0\'c2\'d4\'f6\'d0\'a1\'d6\'fa\'ca\'d6\'99\'7a\'9c\'79\'b8\'fc\'d0\'c2 122 | \f0 & 123 | \f4 \'b1\'ed\'c7\'e9\'b0\'fc\'8f\'cd\'d6\'c6\'b4\'e6\'83\'a6\'b5\'c8\'b5\'c8 124 | \f0 (2018-02-24)}}\cf2 \expnd0\expndtw0\kerning0 125 | \ 126 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.4.0"}}{\fldrslt 127 | \f4 \expnd0\expndtw0\kerning0 128 | \'d0\'c2\'d4\'f6\'b4\'b0\'bf\'da\'d6\'c3\'ed\'94 129 | \f0 & 130 | \f4 \'b6\'e0\'df\'78\'84\'68\'b3\'fd\'b5\'c8\'b5\'c8 131 | \f0 (2017-10-11)}}\cf2 \expnd0\expndtw0\kerning0 132 | \ 133 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.3.0"}}{\fldrslt 134 | \f4 \expnd0\expndtw0\kerning0 135 | \'d0\'c2\'d4\'f6\'d6\'c3\'b5\'d7 136 | \f0 & 137 | \f4 \'c3\'e2\'d5\'4a\'d7\'43 138 | \f0 (2017-09-17)}}\cf2 \expnd0\expndtw0\kerning0 139 | \ 140 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.2.0"}}{\fldrslt 141 | \f4 \expnd0\expndtw0\kerning0 142 | \'d0\'de\'8f\'cd\'c1\'c4\'cc\'ec\'d3\'9b\'e4\'9b\'cf\'fb\'ca\'a7\'b5\'c4 143 | \f0 bug (2017-09-11)}}\cf2 \expnd0\expndtw0\kerning0 144 | \ 145 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.1.0"}}{\fldrslt 146 | \f4 \expnd0\expndtw0\kerning0 147 | \'d6\'d8\'98\'8b\'d7\'d4\'84\'d3\'bb\'d8\'8f\'cd\'a3\'ac\'8c\'8d\'ac\'46\'b6\'e0\'bb\'d8\'8f\'cd 148 | \f0 (2017-08-23)}}\cf2 \expnd0\expndtw0\kerning0 149 | \ 150 | \pard\pardeftab720\sl264\slmult1\partightenfactor0 151 | 152 | \f2\b \cf2 \'d4\'94\'bc\'9a\'83\'c8\'c8\'dd\'d5\'88\'b2\'e9\'bf\'b4{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/blob/master/CHANGELOG.md"}}{\fldrslt 153 | \f0\b0 \cf3 CHANGELOG}} 154 | \f0\b0\fs36\fsmilli18200 \cf2 \ 155 | } -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/A/WeChatPlugin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/A/WeChatPlugin -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module WeChatPlugin { 2 | umbrella header "WeChatPlugin.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/Base.lproj/TKAboutWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/Base.lproj/TKAboutWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/Base.lproj/TKRemoteControlWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/Base.lproj/TKRemoteControlWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 18A391 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | WeChatPlugin 11 | CFBundleIdentifier 12 | tk.WeChatPlugin 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | WeChatPlugin 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 1.7.5 21 | CFBundleSupportedPlatforms 22 | 23 | MacOSX 24 | 25 | CFBundleVersion 26 | 1 27 | DTCompiler 28 | com.apple.compilers.llvm.clang.1_0 29 | DTPlatformBuild 30 | 10B61 31 | DTPlatformVersion 32 | GM 33 | DTSDKBuild 34 | 18B71 35 | DTSDKName 36 | macosx10.14 37 | DTXcode 38 | 1010 39 | DTXcodeBuild 40 | 10B61 41 | NSHumanReadableCopyright 42 | Copyright © 2017年 tk. All rights reserved. 43 | showUpdateWindow 44 | 45 | versionInfo 46 | v1.7.5(2019-01-13):\n👉🏻 适配微信 Version. 2.3.22\n👉🏼 菜单栏新增是否允许微信启动时检测更新(非AppStore版本)\n👉🏽 优化 XML 解析\n\n\n\nv1.7.3 (2018-10-22):\n👉🏻 适配微信 Version. 2.3.19\n👉🏼 修复安全漏洞(请务必更新,若有安装QQ插件也需要更新)\n👉🏽 菜单栏-关于小助手-新增 alfred 开关(若不使用 aflred 可关闭) \n\nv1.7.1 (2018-07-24):\n👉🏻 适配微信 Version. 2.3.17\n👉🏼 新增 alfred 搜索最近聊天列表\n👉🏽 新增 alfred 查看用户聊天记录\n (需更新wechat-alfred-workflow)\n\nv1.7 (2018-05-12):\n👉🏻 新增不同账户设置不同的自动回复&远程控制\n👉🏼 自动回复新增总开关&指定联系人\n👉🏽 远程控制新增控制小助手配置\n👉🏾 新增一键已读\n👉 新增一键清除空回话\n👉🏻 新增国际化(支持英、简、繁)\n👉🏼 新增关于小助手\n👉🏽 新增在线更新小助手 \n👉🏾 去除微信url转链处理(从此直接打开抖音链接🌝 \n👉🏿 修复无法免认证登录&多开等bug \n 47 | 48 | 49 | -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/TKAutoReplyWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/TKAutoReplyWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/TKDownloadWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/TKDownloadWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/TKRemoteControlScript.scpt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/TKRemoteControlScript.scpt -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/en.lproj/Localizable.strings -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/en.lproj/TKAboutWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/en.lproj/TKAboutWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/en.lproj/about.rtfd/TXT.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg936\cocoartf1671 2 | {\fonttbl\f0\fnil\fcharset0 HelveticaNeue-Light;\f1\fnil\fcharset0 HelveticaNeue;\f2\fnil\fcharset0 HelveticaNeue-Bold; 3 | \f3\fnil\fcharset134 PingFangSC-Regular;} 4 | {\colortbl;\red255\green255\blue255;\red38\green38\blue38;\red32\green124\blue169;} 5 | {\*\expandedcolortbl;;\cssrgb\c20000\c20000\c20000;\cssrgb\c14510\c56078\c72157;} 6 | {\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1}} 7 | {\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}} 8 | \margl1440\margr1440\vieww13760\viewh11300\viewkind0 9 | \hyphauto1\hyphfactor90 10 | \deftab720 11 | \pard\pardeftab720\qc\partightenfactor0 12 | 13 | \f0\fs34 \cf2 \expnd0\expndtw0\kerning0 14 | Github: {\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS"}}{\fldrslt \cf3 WeChatPlugin-MacOS}}\ 15 | Email: {\field{\*\fldinst{HYPERLINK "mailto:tkk.ioser@gmail.com"}}{\fldrslt \cf3 tkk.ioser@gmail.com}} 16 | \f1 \ 17 | \pard\pardeftab720\sl288\slmult1\qc\partightenfactor0 18 | 19 | \fs28 \cf2 \ 20 | \pard\pardeftab720\partightenfactor0 21 | 22 | \f2\b\fs34 \cf2 Feature 23 | \fs47\fsmilli23660 \ 24 | \pard\tx220\tx720\pardeftab720\li720\fi-720\sl264\slmult1\partightenfactor0 25 | \ls1\ilvl0 26 | \f0\b0\fs30 \cf2 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 27 | Message auto reply\ 28 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 29 | Prevent message recall\ 30 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 31 | Remote control(support voice control)\ 32 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 33 | Multiple WeChat\ 34 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 35 | Auto Auth Login\ 36 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 37 | Session Sticky Bottom\ 38 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 39 | Windows Sticky Top\ 40 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 41 | Session multiple delete\ 42 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 43 | Auto Login Switch\ 44 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 45 | Quick reply to notifications\ 46 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 47 | Copy or Export Sticker\ 48 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 49 | Update plugin\ 50 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 51 | Reply or Open session by Alfred 52 | \f3\fs32 \ 53 | } -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/zh-Hans.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/zh-Hans.lproj/Localizable.strings -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/zh-Hans.lproj/TKRemoteControlWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/zh-Hans.lproj/TKRemoteControlWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/zh-Hant.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/zh-Hant.lproj/Localizable.strings -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/zh-Hant.lproj/TKAboutWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/zh-Hant.lproj/TKAboutWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/zh-Hant.lproj/TKRemoteControlWindowController.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/Current/Resources/zh-Hant.lproj/TKRemoteControlWindowController.nib -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/Versions/Current/WeChatPlugin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/Versions/Current/WeChatPlugin -------------------------------------------------------------------------------- /Other/Products/Debug/WeChatPlugin.framework/WeChatPlugin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/Products/Debug/WeChatPlugin.framework/WeChatPlugin -------------------------------------------------------------------------------- /Other/ScreenShots/alfred_chat_log.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/alfred_chat_log.gif -------------------------------------------------------------------------------- /Other/ScreenShots/alfred_search.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/alfred_search.gif -------------------------------------------------------------------------------- /Other/ScreenShots/auto_reply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/auto_reply.png -------------------------------------------------------------------------------- /Other/ScreenShots/emotion_copy_export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/emotion_copy_export.png -------------------------------------------------------------------------------- /Other/ScreenShots/en/alfred.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/en/alfred.gif -------------------------------------------------------------------------------- /Other/ScreenShots/en/auto_auth_and_new.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/en/auto_auth_and_new.gif -------------------------------------------------------------------------------- /Other/ScreenShots/en/auto_reply.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/en/auto_reply.gif -------------------------------------------------------------------------------- /Other/ScreenShots/en/emotion_copy_export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/en/emotion_copy_export.png -------------------------------------------------------------------------------- /Other/ScreenShots/en/multiselect_and_stick_bottom_and_clear_empty.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/en/multiselect_and_stick_bottom_and_clear_empty.gif -------------------------------------------------------------------------------- /Other/ScreenShots/en/prevent_recall.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/en/prevent_recall.gif -------------------------------------------------------------------------------- /Other/ScreenShots/en/quick_reply_and_make_read.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/en/quick_reply_and_make_read.gif -------------------------------------------------------------------------------- /Other/ScreenShots/en/remote_control.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/en/remote_control.gif -------------------------------------------------------------------------------- /Other/ScreenShots/en/wechatplugin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/en/wechatplugin.png -------------------------------------------------------------------------------- /Other/ScreenShots/install_download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/install_download.png -------------------------------------------------------------------------------- /Other/ScreenShots/install_terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/install_terminal.png -------------------------------------------------------------------------------- /Other/ScreenShots/notification_quick_reply.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/notification_quick_reply.gif -------------------------------------------------------------------------------- /Other/ScreenShots/remote_control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/remote_control.png -------------------------------------------------------------------------------- /Other/ScreenShots/session_empty_and_clean.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/session_empty_and_clean.gif -------------------------------------------------------------------------------- /Other/ScreenShots/terminal_path.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/terminal_path.png -------------------------------------------------------------------------------- /Other/ScreenShots/voice_remote_control.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/voice_remote_control.gif -------------------------------------------------------------------------------- /Other/ScreenShots/wechatplugin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/ScreenShots/wechatplugin.png -------------------------------------------------------------------------------- /Other/Uninstall.sh: -------------------------------------------------------------------------------- 1 | # !/bin/bash 2 | 3 | wechat_path="/Applications/WeChat.app" 4 | 5 | if [ ! -d "$wechat_path" ] 6 | then 7 | wechat_path="/Applications/微信.app" 8 | if [ ! -d "$wechat_path" ] 9 | then 10 | echo -e "\n\n应用程序文件夹中未发现微信,请检查微信是否有重命名或者移动路径位置" 11 | exit 12 | fi 13 | fi 14 | 15 | app_name="WeChat" 16 | framework_name="WeChatPlugin" 17 | app_bundle_path="${wechat_path}/Contents/MacOS" 18 | app_executable_path="${app_bundle_path}/${app_name}" 19 | app_executable_backup_path="${app_executable_path}_backup" 20 | framework_path="${app_bundle_path}/${framework_name}.framework" 21 | 22 | # 备份WeChat原始可执行文件 23 | if [ -f "$app_executable_backup_path" ] 24 | then 25 | rm "$app_executable_path" 26 | rm -rf "$framework_path" 27 | mv "$app_executable_backup_path" "$app_executable_path" 28 | 29 | if [ -f "$app_executable_backup_path" ] 30 | then 31 | echo "卸载失败,请到 /Applications/WeChat.app/Contents/MacOS 路径,删除 WeChatPlugin.framework、WeChat 两个文件文件,并将 WeChat_backup 重命名为 WeChat" 32 | else 33 | echo "\n\t卸载成功" 34 | fi 35 | 36 | else 37 | echo "\n\t未发现微信小助手" 38 | fi 39 | -------------------------------------------------------------------------------- /Other/Update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | app_name="WeChat" 4 | shell_path="$(dirname "$0")" 5 | wechat_path="/Applications/WeChat.app" 6 | framework_name="WeChatPlugin" 7 | app_bundle_path="/Applications/${app_name}.app/Contents/MacOS" 8 | app_executable_path="${app_bundle_path}/${app_name}" 9 | app_executable_backup_path="${app_executable_path}_backup" 10 | framework_path="${app_bundle_path}/${framework_name}.framework" 11 | 12 | # 对 WeChat 赋予权限 13 | if [ ! -w "$wechat_path" ] 14 | then 15 | echo -e "\n\n为了将小助手写入微信, 请输入密码 : " 16 | sudo chown -R $(whoami) "$wechat_path" 17 | fi 18 | 19 | # 备份 WeChat 原始可执行文件 20 | if [ ! -f "$app_executable_backup_path" ] 21 | then 22 | cp "$app_executable_path" "$app_executable_backup_path" 23 | fi 24 | 25 | cp -r "${shell_path}/Products/Debug/${framework_name}.framework" ${app_bundle_path} 26 | ${shell_path}/insert_dylib --all-yes "${framework_path}/${framework_name}" "$app_executable_backup_path" "$app_executable_path" 27 | ${shell_path}/UpdateRemoteControlCommandsPlist.py 28 | -------------------------------------------------------------------------------- /Other/UpdateRemoteControlCommandsPlist.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | u为老用户自动同步新的plist,不改变已有的entry设置. 6 | """ 7 | 8 | import sys, os 9 | import plistlib 10 | 11 | PLIST_REMOTE_SUB_PATH = 'Products/Debug/WeChatPlugin.framework/Resources/TKRemoteControlCommands.plist' 12 | PLIST_LOCAL_PATH = os.path.expanduser('~') + '/Library/Containers/com.tencent.xinWeChat/Data/Documents/TKWeChatPlugin/' 13 | 14 | def ExportPlistToDict(plist, key): 15 | plist_dic = {} 16 | for l1 in plist: 17 | for l2 in l1: 18 | plist_dic[l2[key]] = l2 19 | return plist_dic 20 | 21 | def SyncPlistContent(remote_plist, local_plist, key): 22 | local_plist_dic = ExportPlistToDict(local_plist, key) 23 | 24 | new_tmp_plist = [] 25 | for l1 in remote_plist: 26 | new_tmp_plist.append([]) 27 | for l2 in l1: 28 | if l2[key] in local_plist_dic: 29 | new_tmp_plist[-1].append(local_plist_dic[l2[key]]) 30 | else: 31 | new_tmp_plist[-1].append(l2) 32 | 33 | return new_tmp_plist 34 | 35 | def main(): 36 | root_path = os.path.dirname(os.path.abspath(sys.argv[0])) + '/' 37 | PLIST_REMOTE_PATH = root_path + PLIST_REMOTE_SUB_PATH 38 | 39 | if not os.path.isfile(PLIST_REMOTE_PATH) or not os.path.exists(PLIST_LOCAL_PATH): 40 | print('Find plist failed... exit') 41 | return 1 42 | 43 | remote_plist = plistlib.readPlist(PLIST_REMOTE_PATH) 44 | 45 | for user in os.listdir(PLIST_LOCAL_PATH): 46 | user_plist_dir = os.path.join(PLIST_LOCAL_PATH, user, 'TKRemoteControlCommands.plist') 47 | if not os.path.isfile(user_plist_dir): 48 | continue 49 | 50 | local_plist = plistlib.readPlist(user_plist_dir) 51 | new_plist = SyncPlistContent(remote_plist, local_plist, 'function') 52 | plistlib.writePlist(new_plist, user_plist_dir) 53 | 54 | return 0 55 | 56 | if __name__ == '__main__': 57 | main() 58 | -------------------------------------------------------------------------------- /Other/insert_dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/Other/insert_dylib -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.12' 2 | inhibit_all_warnings! 3 | 4 | target 'WeChatPlugin' do 5 | pod 'GCDWebServer', '~> 3.4.2' 6 | end 7 | -------------------------------------------------------------------------------- /Q&A.md: -------------------------------------------------------------------------------- 1 | ## 常见问题解决方法: 2 | 3 | ##### 0. 开场: 4 | 由于微信每次更新都会更新一些方法,因此建议可以先备份当前可用的微信.app(~~其实我是不太建议更新的~~),这样避免微信更新之后,小助手部分功能失效或者闪退。 5 | 6 | --- 7 | 8 | ##### 1. 为什么我更新微信之后菜单栏小助手不见了? 9 | 10 | 因为微信更新之后,整个 app 都被覆盖,所以小助手也被清空,这时候只要重新安装小助手即可。 11 | 12 | --- 13 | 14 | ##### 2. 为什么更新了微信之后闪退/崩溃? 15 | 16 | 因为微信更换了API,导致小助手找不到对应的方法、函数,因此崩溃,解决方法有两种:1. 下载旧版本的微信。2.卸载微信小助手。 17 | 18 | --- 19 | 20 | ##### 3. 有没有微信群或者 QQ群讨论? 21 | 22 | 没有,目前没有这个打算。 23 | 24 | --- 25 | 26 | ##### 4. omw 无法安装或者是安装时候不是最新? 27 | 28 | omw 的问题可以去 [oh-my-wechat](https://github.com/lmk123/oh-my-wechat) 提 issue,这样作者能够及时解决。 29 | 如果使用omw更新小助手不是最新的,可以使用其他安装方法试试。 30 | 31 | --- 32 | 33 | ##### 5. 如何卸载小助手? 34 | 35 | 在终端执行 Other 文件夹中的 Uninstall.sh,如果无效的话,那么再终端执行以下代码: 36 | 37 | `cd /Applications/WeChat.app/Contents/MacOS && mv WeChat_backup WeChat` 38 | 39 | 如果在无效,那么请在Finder中应用程序中,右击微信.app,查看包内容,打开目录`/Contents/MacOS `,将`WeChat_backup`改名为 `WeChat` 40 | 41 | --- 42 | 43 | ##### 6. 如何禁止微信更新? 44 | 45 | 可以下载小助手1.7.5,如果是从官网下载,点击菜单栏的`微信小助手`-`禁止微信启动时检测更新`,如果是从 App Store,那么请在 App Store 中设置去除自动更新下载。 46 | 47 | ##### 7. 能不能做朋友圈或者微信抢红包? 48 | 49 | * 不能,朋友圈工作量大,细节多,没有那么多的时间。 50 | * 抢红包是不可能的,这辈子都不可能的,因为也没有人给我发红包。 51 | 52 | --- 53 | 54 | ##### 8. 能不能做群管理或者是自动添加好友? 55 | 56 | 不能,目前如果是有点微商性质的功能还是尽量避免,避免打扰到别人。 57 | 58 | --- 59 | 60 | ##### 9. 能不能做群发消息或者定时发送消息? 61 | 62 | 不能,目前如果是有点微商性质的功能还是尽量避免,避免打扰到别人。 63 | 64 | --- 65 | 66 | ##### 10. 为什么不支持企业微信? 67 | 68 | 企业微信跟普通的微信是两个app,方法也不一样,另外本人没有使用企业微信,因此不打算。 69 | 70 | --- 71 | 72 | ##### 11. 为什么菜单栏的小助手无法点击? 73 | 74 | 因为目前小助手的功能是分账号设置的,因为如果用户退出登录的话,那么将无法点击,只有重新登录微信才行。 75 | 76 | --- 77 | 78 | ##### 12. Safari /共享无法分享到微信? 79 | 80 | 目前无法解决。 81 | 82 | --- 83 | 84 | ##### 13. 休眠无法自动同步微信消息? 85 | 86 | 目前还无法解决。 87 | 88 | --- 89 | 90 | ##### 14. 作者是不是不更新了? 91 | 92 | * 作者的目标是一年两更,现在已达标完成了。 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Forked from tk 2 | 3 | ### Other 4 | https://github.com/MustangYM/WeChatExtension-ForMac 5 | -------------------------------------------------------------------------------- /README_EN.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ![wechat assistant.png](./Other/ScreenShots/en/wechatplugin.png) 4 | 5 | ![platform](https://img.shields.io/badge/platform-macos-lightgrey.svg) [![release](https://img.shields.io/badge/release-v1.7-brightgreen.svg)](https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases) ![support](https://img.shields.io/badge/support-wechat%202.3.10-blue.svg) [![Readme](https://img.shields.io/badge/readme-中文-yellow.svg)](./README.md) [![GitHub license](https://img.shields.io/github/license/TKkk-iOSer/WeChatPlugin-MacOS.svg)](https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/blob/master/LICENSE) 6 | 7 | # WeChatPlugin-macOS v1.7 8 | 9 | **English | [中文](./README.md)** 10 | 11 | [ [Feature](#feature) • [Install](#install) • [Uninstall](#uninstall) • [Usage](#usage)] 12 | 13 | Other plugin: 14 | [ [wechat-alfred-workflow](https://github.com/TKkk-iOSer/wechat-alfred-workflow) • [QQPlugin-macOS](https://github.com/TKkk-iOSer/QQPlugin-macOS) • [WeChatPlugin-iOS](https://github.com/TKkk-iOSer/WeChatPlugin-iOS) ] 15 | 16 | --- 17 | 18 | ## Feature 19 | 20 | * Message auto reply 21 | * Prevent message recall 22 | * Remote control(support voice control) 23 | * Multiple WeChat 24 | * Auto Auth Login 25 | * Session Sticky Bottom 26 | * Windows Sticky Top 27 | * Session multiple delete 28 | * Auto Login Switch 29 | * Quick reply to notifications 30 | * Copy or Export Sticker 31 | * Update plugin 32 | * Reply or Open session by Alfred (dependency:[wechat-alfred-workflow](https://github.com/TKkk-iOSer/wechat-alfred-workflow)) 33 | * Make all session As Read 34 | * Clear all empty session 35 | * Remove url redirect 36 | 37 | Remote Control: 38 | 39 | - [x] Save Screen 40 | - [x] Empty Trash 41 | - [x] Lock Screen & Sleep & Shut Down & Restart 42 | - [x] Quit some app, include QQ、WeChat、Chrome、Safari。 43 | - [x] NeteaseMusic(play、pause、next song、previous song、like song、unlike song) 44 | - [x] Assistant(get all directive、prevent recall switch、auto reply switch、auto auth switch) 45 | 46 | **If you want to control NeteaseMusic, please allow WeChat Control in "System Preferences-Security & Privacy-Privacy-Accessibility"** 47 | 48 | --- 49 | 50 | ## Install 51 | 52 | **1. If you have installed Git** 53 | 54 | open `/Applications/Utilities/Terminal.app`,run command 55 | 56 | `cd ~/Downloads && rm -rf WeChatPlugin-MacOS && git clone https://github.com/TKkk-iOSer/WeChatPlugin-MacOS.git --depth=1 && ./WeChatPlugin-MacOS/Other/Install.sh`, and enter the mac password. 57 | 58 | **2. Normal install** 59 | 60 | * click `clone or download` button to download project and unzip it,open Terminal.app,Drag the `Install.sh` file(in `Other` Folder) to Terminal. 61 | 62 | --- 63 | 64 | ## Uninstall 65 | open `/Applications/Utilities/Terminal.app`,Drag the `Uninstall.sh` file(in `Other` Folder) to Terminal. 66 | 67 | --- 68 | 69 | ## Usage 70 | 71 | > A few examples of how to use WeChatPlugin-macOS. 72 | 73 | * Prevent message recall 74 | ![Prevent message recall](./Other/ScreenShots/en/prevent_recall.gif) 75 | 76 | * Message auto reply 77 | ![Message auto reply](./Other/ScreenShots/en/auto_reply.gif) 78 | 79 | * Auto Login & Multiple WeChat 80 | ![Auto Auth & Multiple WeChat](./Other/ScreenShots/en/auto_auth_and_new.gif) 81 | 82 | * Remote control (quit Chrome and Save Screen) 83 | ![remote_control.gif](./Other/ScreenShots/en/remote_control.gif) 84 | 85 | * Session multiple delete & session sticky bottom & delete empty session 86 | ![wechat assistant.png](./Other/ScreenShots/en/multiselect_and_stick_bottom_and_clear_empty.gif) 87 | 88 | 89 | * Quick reply to notifications & make all as Read 90 | ![wechat assistant.png](./Other/ScreenShots/en/quick_reply_and_make_read.gif) 91 | 92 | 93 | * Copy or export sticker 94 | 95 | 96 | * Reply or Open session by Alfred [wechat-alfred-workflow](https://github.com/TKkk-iOSer/wechat-alfred-workflow) 97 | ![Alfred](./Other/ScreenShots/en/alfred.gif) 98 | 99 | 100 | --- 101 | 102 | ## Dependency 103 | 104 | * [insert_dylib](https://github.com/Tyilo/insert_dylib) 105 | * [fishhook](https://github.com/facebook/fishhook) 106 | * [GCDWebServer](https://github.com/swisspol/GCDWebServer) 107 | 108 | 109 | -------------------------------------------------------------------------------- /WeChatPlugin.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WeChatPlugin.xcodeproj/xcuserdata/TK.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /WeChatPlugin.xcodeproj/xcuserdata/TK.xcuserdatad/xcschemes/WeChatPlugin.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 49 | 50 | 51 | 57 | 58 | 59 | 60 | 61 | 62 | 68 | 69 | 75 | 76 | 77 | 78 | 80 | 81 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /WeChatPlugin.xcodeproj/xcuserdata/TK.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WeChatPlugin.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 528B4F911EA7383800BC6A89 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /WeChatPlugin.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /WeChatPlugin.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /WeChatPlugin.xcworkspace/xcuserdata/TK.xcuserdatad/IDEFindNavigatorScopes.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /WeChatPlugin.xcworkspace/xcuserdata/TK.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /WeChatPlugin/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.7.5 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSHumanReadableCopyright 22 | Copyright © 2017年 tk. All rights reserved. 23 | NSPrincipalClass 24 | 25 | showUpdateWindow 26 | 27 | versionInfo 28 | v1.7.5(2019-01-13):\n👉🏻 适配微信 Version. 2.3.22\n👉🏼 菜单栏新增是否允许微信启动时检测更新(非AppStore版本)\n👉🏽 优化 XML 解析\n\n\n\nv1.7.3 (2018-10-22):\n👉🏻 适配微信 Version. 2.3.19\n👉🏼 修复安全漏洞(请务必更新,若有安装QQ插件也需要更新)\n👉🏽 菜单栏-关于小助手-新增 alfred 开关(若不使用 aflred 可关闭) \n\nv1.7.1 (2018-07-24):\n👉🏻 适配微信 Version. 2.3.17\n👉🏼 新增 alfred 搜索最近聊天列表\n👉🏽 新增 alfred 查看用户聊天记录\n (需更新wechat-alfred-workflow)\n\nv1.7 (2018-05-12):\n👉🏻 新增不同账户设置不同的自动回复&远程控制\n👉🏼 自动回复新增总开关&指定联系人\n👉🏽 远程控制新增控制小助手配置\n👉🏾 新增一键已读\n👉 新增一键清除空回话\n👉🏻 新增国际化(支持英、简、繁)\n👉🏼 新增关于小助手\n👉🏽 新增在线更新小助手 \n👉🏾 去除微信url转链处理(从此直接打开抖音链接🌝 \n👉🏿 修复无法免认证登录&多开等bug \n 29 | 30 | 31 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Category/NSButton+Action.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSButton+Action.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/9/19. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSButton (Action) 12 | 13 | + (instancetype)tk_buttonWithTitle:(NSString *)title target:(id)target action:(SEL)action; 14 | + (instancetype)tk_checkboxWithTitle:(NSString *)title target:(id)target action:(SEL)action; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Category/NSButton+Action.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSButton+Action.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/9/19. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import "NSButton+Action.h" 10 | 11 | @implementation NSButton (Action) 12 | 13 | + (instancetype)tk_checkboxWithTitle:(NSString *)title target:(id)target action:(SEL)action { 14 | NSButton *btn = [self tk_buttonWithTitle:title target:target action:action]; 15 | [btn setButtonType:NSButtonTypeSwitch]; 16 | 17 | return btn; 18 | } 19 | 20 | + (instancetype)tk_buttonWithTitle:(NSString *)title target:(id)target action:(SEL)action { 21 | NSButton *btn = ({ 22 | NSButton *btn = [[self alloc] init]; 23 | btn.title = title; 24 | btn.target = target; 25 | btn.action = action; 26 | 27 | btn; 28 | }); 29 | 30 | return btn; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Category/NSDate+Action.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+Action.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/7/25. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDate (Action) 12 | 13 | - (BOOL)isToday; 14 | - (BOOL)isYesterday; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Category/NSDate+Action.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+Action.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/7/25. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import "NSDate+Action.h" 10 | 11 | @implementation NSDate (Action) 12 | 13 | - (BOOL)isToday { 14 | NSCalendar *calendar = [NSCalendar currentCalendar]; 15 | NSInteger unit = NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear ; 16 | 17 | NSDateComponents *nowComponents = [calendar components:unit fromDate:[NSDate date]]; 18 | NSDateComponents *selfComponents = [calendar components:unit fromDate:self]; 19 | 20 | return (selfComponents.year == nowComponents.year) && (selfComponents.month == nowComponents.month) && (selfComponents.day == nowComponents.day); 21 | } 22 | 23 | - (BOOL)isYesterday { 24 | NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 25 | formatter.dateFormat = @"yyyy-MM-dd"; 26 | 27 | NSDate *nowDate = [formatter dateFromString:[formatter stringFromDate:[NSDate date]]]; 28 | NSDate *selfDate = [formatter dateFromString:[formatter stringFromDate:self]];; 29 | NSCalendar *calendar = [NSCalendar currentCalendar]; 30 | NSDateComponents *cmps = [calendar components:NSCalendarUnitDay fromDate:selfDate toDate:nowDate options:0]; 31 | 32 | return cmps.day == 1; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Category/NSMenu+Action.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMenu+Action.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/4/15. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSMenu (Action) 12 | 13 | - (void)addItems:(NSArray *)subItems; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Category/NSMenu+Action.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMenu+Action.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/4/15. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import "NSMenu+Action.h" 10 | 11 | @implementation NSMenu (Action) 12 | 13 | - (void)addItems:(NSArray *)subItems { 14 | for (NSMenuItem *item in subItems) { 15 | NSAssert([item isKindOfClass:[NSMenuItem class]], @"the elements must be a NSMenuItem!"); 16 | [self addItem:item]; 17 | } 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Category/NSMenuItem+Action.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMenuItem+Action.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/4/25. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSMenuItem (Action) 12 | 13 | + (NSMenuItem *)menuItemWithTitle:(NSString *)title action:(SEL)selector target:(id)target keyEquivalent:(NSString *)key state:(NSControlStateValue)state; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Category/NSMenuItem+Action.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMenuItem+Action.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/4/25. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import "NSMenuItem+Action.h" 10 | 11 | @implementation NSMenuItem (Action) 12 | 13 | + (NSMenuItem *)menuItemWithTitle:(NSString *)title action:(SEL)selector target:(id)target keyEquivalent:(NSString *)key state:(NSControlStateValue)state { 14 | NSMenuItem *item = [[self alloc] initWithTitle:title action:selector keyEquivalent:key]; 15 | item.target = target; 16 | item.state = state; 17 | 18 | return item; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Category/NSString+Action.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Action.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/5/1. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (Action) 12 | 13 | - (CGFloat)widthWithFont:(NSFont *)font; 14 | - (NSRect)rectWithFont:(NSFont *)font; 15 | - (NSString *)substringFromString:(NSString *)fromStr; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Category/NSString+Action.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Action.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/5/1. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import "NSString+Action.h" 10 | 11 | @implementation NSString (Action) 12 | 13 | - (CGFloat)widthWithFont:(NSFont *)font { 14 | return [self rectWithFont:font].size.width; 15 | } 16 | 17 | - (NSRect)rectWithFont:(NSFont *)font { 18 | return [self boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: font}]; 19 | } 20 | 21 | - (NSString *)substringFromString:(NSString *)fromStr { 22 | NSRange range = [self rangeOfString:fromStr]; 23 | if (range.length > 0) { 24 | return [self substringFromIndex:range.location + range.length]; 25 | } 26 | return nil; 27 | } 28 | @end 29 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Category/NSTextField+Action.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSTextField+Action.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/9/19. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSTextField (Action) 12 | 13 | + (instancetype)tk_labelWithString:(NSString *)stringValue; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Category/NSTextField+Action.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSTextField+Action.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/9/19. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import "NSTextField+Action.h" 10 | 11 | @implementation NSTextField (Action) 12 | 13 | + (instancetype)tk_labelWithString:(NSString *)stringValue { 14 | NSTextField *textField = ({ 15 | NSTextField *textField = [[self alloc] initWithFrame:NSMakeRect(10, 10, 200, 17)]; 16 | [textField setStringValue:stringValue]; 17 | [textField setBezeled:NO]; 18 | [textField setDrawsBackground:NO]; 19 | [textField setEditable:NO]; 20 | [textField setSelectable:NO]; 21 | 22 | textField; 23 | }); 24 | 25 | return textField; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Category/NSView+Action.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSView+Action.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/8/20. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSView (Action) 12 | 13 | - (void)addSubviews:(NSArray *)subViews; 14 | 15 | @end 16 | 17 | @interface NSView (Size) 18 | 19 | @property (nonatomic) CGPoint origin; 20 | @property (nonatomic) CGSize size; 21 | @property (nonatomic) CGFloat x; 22 | @property (nonatomic) CGFloat y; 23 | @property (nonatomic) CGFloat width; 24 | @property (nonatomic) CGFloat height; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Category/NSView+Action.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSView+Action.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/8/20. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import "NSView+Action.h" 10 | 11 | @implementation NSView (Action) 12 | 13 | - (void)addSubviews:(NSArray *)subViews { 14 | for (NSView *v in subViews) { 15 | NSAssert([v isKindOfClass:[NSView class]], @"the elements must be a view!"); 16 | [self addSubview:v]; 17 | } 18 | } 19 | 20 | @end 21 | 22 | @implementation NSView (Size) 23 | 24 | - (CGPoint)origin { 25 | return self.frame.origin; 26 | } 27 | 28 | - (void)setOrigin:(CGPoint)point { 29 | CGRect rect = self.frame; 30 | 31 | rect.origin = point; 32 | self.frame = rect; 33 | } 34 | 35 | - (CGSize)size { 36 | return self.frame.size; 37 | } 38 | 39 | - (void)setSize:(CGSize)size { 40 | CGRect rect = self.frame; 41 | 42 | rect.size = size; 43 | self.frame = rect; 44 | } 45 | 46 | - (CGFloat)x { 47 | return self.frame.origin.x; 48 | } 49 | 50 | - (void)setX:(CGFloat)x { 51 | [self setOrigin:CGPointMake(x, self.y)]; 52 | } 53 | 54 | - (CGFloat)y { 55 | return self.frame.origin.y; 56 | } 57 | 58 | - (void)setY:(CGFloat)y { 59 | [self setOrigin:CGPointMake(self.x, y)]; 60 | } 61 | 62 | - (CGFloat)width { 63 | return self.frame.size.width; 64 | } 65 | 66 | - (void)setWidth:(CGFloat)width { 67 | [self setSize:CGSizeMake(width, self.height)]; 68 | } 69 | 70 | - (CGFloat)height { 71 | return self.frame.size.height; 72 | } 73 | 74 | - (void)setHeight:(CGFloat)height { 75 | [self setSize:CGSizeMake(self.width, height)]; 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Category/NSWindowController+Action.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSWindowController+Action.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/5/4. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSWindowController (Action) 12 | 13 | - (void)show; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Category/NSWindowController+Action.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSWindowController+Action.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/5/4. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import "NSWindowController+Action.h" 10 | 11 | @implementation NSWindowController (Action) 12 | 13 | - (void)show { 14 | [self showWindow:self]; 15 | [self.window center]; 16 | [self.window makeKeyWindow]; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Macro/ColorConstant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Color.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/8/20. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #ifndef Color_h 10 | #define Color_h 11 | 12 | #define TK_RGBA(r, g, b, a) [NSColor colorWithRed:(r) / 255.0 \ 13 | green:(g) / 255.0 \ 14 | blue:(b) / 255.0 \ 15 | alpha:(a)] 16 | 17 | #define TK_RGB(r, g, b) TK_RGBA(r, g, b, 1.0) 18 | #define TK_GRAYA(c, a) TK_RGBA(c, c, c, a) 19 | #define TK_GRAY(c) TK_GRAYA(c, 1.0) 20 | 21 | #define kBG1 TK_GRAY(0xec) 22 | #define kBG2 TK_GRAY(0xe3) 23 | #define kBG3 TK_GRAYA(0x2a, 0.5) 24 | #define kBG4 TK_GRAYA(0x7a, 0.5) 25 | 26 | #endif /* Color_h */ 27 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Macro/DefineConstant.h: -------------------------------------------------------------------------------- 1 | // 2 | // DefineConstant.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/4/14. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #ifndef DefineConstant_h 10 | #define DefineConstant_h 11 | 12 | #define TKLocalizedString(key) [[NSBundle bundleWithIdentifier:@"tk.WeChatPlugin"] localizedStringForKey:(key) value:@"" table:nil] 13 | #define WXLocalizedString(key) [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil] 14 | 15 | #endif /* DefineConstant_h */ 16 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/Macro/NotifyConstant.h: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // NotifyConstant.h.h 4 | // WeChatPlugin 5 | // 6 | // Created by TK on 2018/4/23. 7 | // Copyright © 2018年 tk. All rights reserved. 8 | // 9 | 10 | #import 11 | 12 | #ifndef NotifyConstant_h_h 13 | #define NotifyConstant_h_h 14 | 15 | static NSString * const NOTIFY_AUTO_REPLY_CHANGE = @"NOTIFY_AUTO_REPLY_CHANGE"; 16 | static NSString * const NOTIFY_PREVENT_REVOKE_CHANGE = @"NOTIFY_PREVENT_REVOKE_CHANGE"; 17 | static NSString * const NOTIFY_AUTO_AUTH_CHANGE = @"NOTIFY_AUTO_AUTH_CHANGE"; 18 | 19 | #endif /* NotifyConstant_h_h */ 20 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Common/TKPrefixHeader.pch: -------------------------------------------------------------------------------- 1 | // 2 | // TKPrefixHeader.pch 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/8/20. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #ifndef TKPrefixHeader_pch 10 | #define TKPrefixHeader_pch 11 | 12 | #ifdef __OBJC__ 13 | #import "ColorConstant.h" 14 | #import "DefineConstant.h" 15 | #import "NotifyConstant.h" 16 | #import "NSView+Action.h" 17 | #import "NSButton+Action.h" 18 | #import "NSTextField+Action.h" 19 | #import "NSMenu+Action.h" 20 | #import "NSString+Action.h" 21 | #import "NSDate+Action.h" 22 | #import "NSWindowController+Action.h" 23 | #import "WeChatPlugin.h" 24 | #import "TKUtility.h" 25 | #endif 26 | 27 | #endif /* TKPrefixHeader_pch */ 28 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Config/TKWeChatPluginConfig.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKWeChatPluginConfig.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/4/19. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | 12 | @interface TKWeChatPluginConfig : NSObject 13 | 14 | @property (nonatomic, assign) BOOL preventRevokeEnable; /**< 是否开启防撤回 */ 15 | @property (nonatomic, assign) BOOL preventSelfRevokeEnable; /**< 是否防撤回自己 */ 16 | @property (nonatomic, assign) BOOL autoReplyEnable; /**< 是否开启自动回复 */ 17 | @property (nonatomic, assign) BOOL autoAuthEnable; /**< 是否免认证登录 */ 18 | @property (nonatomic, assign) BOOL autoLoginEnable; /**< 是否自动登录 */ 19 | @property (nonatomic, assign) BOOL onTop; /**< 是否要置顶微信 */ 20 | @property (nonatomic, assign) BOOL multipleSelectionEnable; /**< 是否要进行多选 */ 21 | @property (nonatomic, assign) BOOL forbidCheckVersion; /**< 禁止检测版本 */ 22 | @property (nonatomic, assign) BOOL alfredEnable; /**< 是否开启Alfred */ 23 | @property (nonatomic, assign) BOOL checkUpdateWechatEnable; /**< 是否允许微信启动检测更新 */ 24 | @property (nonatomic, assign) BOOL systemBrowserEnable; /**< 是否使用自身浏览器打开连接 */ 25 | @property (nonatomic, strong) NSMutableArray *autoReplyModels; /**< 自动回复的数组 */ 26 | @property (nonatomic, strong) NSMutableArray *remoteControlModels; /**< 远程控制的数组 */ 27 | @property (nonatomic, strong) NSMutableArray *ignoreSessionModels; /**< 聊天置底的数组 */ 28 | @property (nonatomic, strong) NSMutableArray *selectSessions; /**< 已经选中的会话 */ 29 | @property (nonatomic, strong) NSMutableSet *revokeMsgSet; /**< 撤回的消息集合 */ 30 | @property (nonatomic, strong) NSMutableSet *unreadSessionSet; /**< 标记未读消息集合 */ 31 | @property (nonatomic, copy) NSString *currentUserName; /**< 当前用户的id */ 32 | @property (nonatomic, copy, readonly) NSDictionary *localInfoPlist; 33 | @property (nonatomic, copy, readonly) NSDictionary *romoteInfoPlist; 34 | 35 | - (void)saveAutoReplyModels; 36 | - (void)saveRemoteControlModels; 37 | - (void)saveIgnoreSessionModels; 38 | 39 | + (instancetype)sharedConfig; 40 | 41 | @end 42 | 43 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Hook/MMChatsTableCellView+hook.h: -------------------------------------------------------------------------------- 1 | // 2 | // MMChatsTableCellView+hook.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/9/15. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSObject (MMChatsTableCellViewHook) 12 | 13 | + (void)hookMMChatsTableCellView; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Hook/MMStickerMessageCellView+hook.h: -------------------------------------------------------------------------------- 1 | // 2 | // MMStickerMessageCellView+hook.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/2/23. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSObject (MMStickerMessageCellView) 12 | 13 | + (void)hookMMStickerMessageCellView; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Hook/MMStickerMessageCellView+hook.m: -------------------------------------------------------------------------------- 1 | // 2 | // MMStickerMessageCellView+hook.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/2/23. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import "MMStickerMessageCellView+hook.h" 10 | #import "WeChatPlugin.h" 11 | 12 | @implementation NSObject (MMStickerMessageCellView) 13 | 14 | + (void)hookMMStickerMessageCellView { 15 | tk_hookMethod(objc_getClass("MMStickerMessageCellView"), @selector(contextMenu), [self class], @selector(hook_contextMenu)); 16 | if (LargerOrEqualVersion(@"2.3.22")) { 17 | tk_hookMethod(objc_getClass("MMStickerMessageCellView"), @selector(contextMenuExport), [self class], @selector(hook_contextMenuExport)); 18 | } 19 | } 20 | 21 | - (id)hook_contextMenu { 22 | NSMenu *menu = [self hook_contextMenu]; 23 | if ([self.className isEqualToString:@"MMStickerMessageCellView"]) { 24 | NSMenuItem *copyItem = [[NSMenuItem alloc] initWithTitle:WXLocalizedString(@"Message.Menu.Copy") action:@selector(contextMenuCopyEmoji) keyEquivalent:@""]; 25 | NSMenuItem *exportItem = [[NSMenuItem alloc] initWithTitle:WXLocalizedString(@"Message.Menu.Export") action:@selector(contextMenuExport) keyEquivalent:@""]; 26 | [menu addItem:[NSMenuItem separatorItem]]; 27 | [menu addItem:copyItem]; 28 | [menu addItem:exportItem]; 29 | } 30 | return menu; 31 | } 32 | 33 | - (void)contextMenuExport { 34 | [self exportEmoji]; 35 | } 36 | 37 | - (void)hook_contextMenuExport { 38 | if (![self.className isEqualToString:@"MMStickerMessageCellView"]) { 39 | [self hook_contextMenu]; 40 | return; 41 | } 42 | [self exportEmoji]; 43 | } 44 | 45 | - (void)exportEmoji { 46 | MMStickerMessageCellView *currentCellView = (MMStickerMessageCellView *)self; 47 | MMMessageTableItem *item = currentCellView.messageTableItem; 48 | if (!item.message || !item.message.m_nsEmoticonMD5) { 49 | return; 50 | } 51 | EmoticonMgr *emoticonMgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("EmoticonMgr")]; 52 | NSData *imageData = [emoticonMgr getEmotionDataWithMD5:item.message.m_nsEmoticonMD5]; 53 | if (!imageData) return; 54 | 55 | NSSavePanel *savePanel = ({ 56 | NSSavePanel *panel = [NSSavePanel savePanel]; 57 | [panel setDirectoryURL:[NSURL fileURLWithPath:[NSHomeDirectory() stringByAppendingPathComponent:@"Pictures"]]]; 58 | [panel setNameFieldStringValue:item.message.m_nsEmoticonMD5]; 59 | [panel setAllowedFileTypes:@[[NSObject getTypeForImageData:imageData]]]; 60 | [panel setAllowsOtherFileTypes:YES]; 61 | [panel setExtensionHidden:NO]; 62 | [panel setCanCreateDirectories:YES]; 63 | 64 | panel; 65 | }); 66 | [savePanel beginSheetModalForWindow:currentCellView.delegate.view.window completionHandler:^(NSInteger result) { 67 | if (result == NSModalResponseOK) { 68 | [imageData writeToFile:[[savePanel URL] path] atomically:YES]; 69 | } 70 | }]; 71 | } 72 | 73 | - (void)contextMenuCopyEmoji { 74 | if ([self.className isEqualToString:@"MMStickerMessageCellView"]) { 75 | MMMessageTableItem *item = [self valueForKey:@"messageTableItem"]; 76 | if (!item.message || !item.message.m_nsEmoticonMD5) { 77 | return; 78 | } 79 | EmoticonMgr *emoticonMgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("EmoticonMgr")]; 80 | NSData *imageData = [emoticonMgr getEmotionDataWithMD5:item.message.m_nsEmoticonMD5]; 81 | if (!imageData) return; 82 | 83 | NSString *imageType = [NSObject getTypeForImageData:imageData]; 84 | NSString *imageName = [NSString stringWithFormat:@"temp_paste_image_%@.%@", item.message.m_nsEmoticonMD5, imageType]; 85 | NSString *tempImageFilePath = [NSTemporaryDirectory() stringByAppendingString:imageName]; 86 | NSURL *imageUrl = [NSURL fileURLWithPath:tempImageFilePath]; 87 | [imageData writeToURL:imageUrl atomically:YES]; 88 | 89 | NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; 90 | [pasteboard clearContents]; 91 | [pasteboard declareTypes:@[NSFilenamesPboardType] owner:nil]; 92 | [pasteboard writeObjects:@[imageUrl]]; 93 | } 94 | } 95 | 96 | + (NSString *)getTypeForImageData:(NSData *)data { 97 | uint8_t c; 98 | [data getBytes:&c length:1]; 99 | switch (c) { 100 | case 0x89: 101 | return @"png"; 102 | case 0x47: 103 | return @"gif"; 104 | default: 105 | return @"jpg"; 106 | } 107 | return nil; 108 | } 109 | 110 | @end 111 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Hook/WeChat+hook.h: -------------------------------------------------------------------------------- 1 | // 2 | // WeChat+hook.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/4/19. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSObject (WeChatHook) 12 | 13 | + (void)hookWeChat; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Managers/TKAssistantMenuManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKAssistantMenuManager.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/4/24. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TKAssistantMenuManager : NSObject 12 | 13 | + (instancetype)shareManager; 14 | - (void)initAssistantMenuItems; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Managers/TKCacheManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKCacheManager.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/8/3. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TKCacheManager : NSObject 12 | 13 | + (instancetype)shareManager; 14 | 15 | - (BOOL)fileExistsWithName:(NSString *)fileName; 16 | - (NSString *)filePathWithName:(NSString *)fileName; 17 | - (NSString *)cacheEmotionMessage:(MessageData *)emotionMsg; 18 | - (NSString *)cacheAvatarWithContact:(WCContactData *)contact; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Managers/TKCacheManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // TKCacheManager.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/8/3. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import "TKCacheManager.h" 10 | 11 | @interface TKCacheManager () 12 | 13 | @property (nonatomic, copy) NSString *cacheDirectory; 14 | @property (nonatomic, strong) NSMutableSet *emotionSet; 15 | @property (nonatomic, strong) NSMutableSet *avatarSet; 16 | @end 17 | 18 | @implementation TKCacheManager 19 | 20 | + (instancetype)shareManager { 21 | static TKCacheManager *manager = nil; 22 | static dispatch_once_t onceToken; 23 | dispatch_once(&onceToken, ^{ 24 | manager = [[TKCacheManager alloc] init]; 25 | }); 26 | return manager; 27 | } 28 | 29 | - (instancetype)init 30 | { 31 | self = [super init]; 32 | if (self) { 33 | self.cacheDirectory = [NSTemporaryDirectory() stringByAppendingString:@"TKWeChatPlugin/"]; 34 | NSFileManager *manager = [NSFileManager defaultManager]; 35 | if (![manager fileExistsAtPath:self.cacheDirectory]) { 36 | [manager createDirectoryAtPath:self.cacheDirectory withIntermediateDirectories:YES attributes:nil error:nil]; 37 | } 38 | 39 | MMExtensionCenter *extensionCenter = [[objc_getClass("MMServiceCenter") defaultCenter] getService:[objc_getClass("MMExtensionCenter") class]]; 40 | MMExtension *extension = [extensionCenter getExtension:@protocol(EmoticonDownloadMgrExt)]; 41 | if (extension) { 42 | [extension registerExtension:self]; 43 | } 44 | 45 | self.emotionSet = [NSMutableSet set]; 46 | self.avatarSet = [NSMutableSet set]; 47 | } 48 | return self; 49 | } 50 | 51 | - (void)dealloc { 52 | MMExtensionCenter *extensionCenter = [[objc_getClass("MMServiceCenter") defaultCenter] getService:[objc_getClass("MMExtensionCenter") class]]; 53 | MMExtension *extension = [extensionCenter getExtension:@protocol(EmoticonDownloadMgrExt)]; 54 | if (extension) { 55 | [extension unregisterExtension:self]; 56 | } 57 | } 58 | 59 | - (BOOL)fileExistsWithName:(NSString *)fileName { 60 | fileName = [fileName stringByAppendingString:@".gif"]; 61 | NSString *filePath = [self.cacheDirectory stringByAppendingString:fileName]; 62 | NSFileManager *manager = [NSFileManager defaultManager]; 63 | return [manager fileExistsAtPath:filePath]; 64 | } 65 | 66 | - (NSString *)filePathWithName:(NSString *)fileName { 67 | if (![self fileExistsWithName:fileName]) return nil; 68 | 69 | fileName = [fileName stringByAppendingString:@".gif"]; 70 | return [self.cacheDirectory stringByAppendingString:fileName]; 71 | } 72 | 73 | - (NSString *)cacheImageData:(NSData *)imageData withFileName:(NSString *)fileName completion:(void (^)(BOOL))completion { 74 | BOOL result = NO; 75 | if (!imageData) { 76 | if (completion) { 77 | completion(result); 78 | } 79 | } 80 | NSString *imageName = [NSString stringWithFormat:@"%@.gif", fileName]; 81 | NSString *tempImageFilePath = [self.cacheDirectory stringByAppendingString:imageName]; 82 | if (imageData) { 83 | NSURL *imageUrl = [NSURL fileURLWithPath:tempImageFilePath]; 84 | result = [imageData writeToURL:imageUrl atomically:YES]; 85 | } 86 | 87 | if (completion) { 88 | completion(result); 89 | } 90 | return tempImageFilePath; 91 | } 92 | 93 | - (NSString *)cacheEmotionMessage:(MessageData *)emotionMsg { 94 | EmoticonMgr *emoticonMgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("EmoticonMgr")]; 95 | NSData *imageData = [emoticonMgr getEmotionDataWithMD5:emotionMsg.m_nsEmoticonMD5]; 96 | if (!imageData && ![self.emotionSet containsObject:emotionMsg.m_nsEmoticonMD5]) { 97 | EmoticonDownloadMgr *emotionMgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("EmoticonDownloadMgr")]; 98 | [emotionMgr downloadEmoticonWithMessageData:emotionMsg]; 99 | [self.emotionSet addObject:emotionMsg.m_nsEmoticonMD5]; 100 | } 101 | NSString *tempImageFilePath = [self cacheImageData:imageData withFileName:emotionMsg.m_nsEmoticonMD5 completion:nil]; 102 | 103 | return tempImageFilePath; 104 | } 105 | 106 | - (void)emoticonDownloadFinished:(EmoticonMsgInfo *)msgInfo { 107 | if (![self.emotionSet containsObject:msgInfo.m_nsMD5]) return; 108 | 109 | EmoticonMgr *emoticonMgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("EmoticonMgr")]; 110 | NSData *imageData = [emoticonMgr getEmotionDataWithMD5:msgInfo.m_nsMD5]; 111 | [self cacheImageData:imageData withFileName:msgInfo.m_nsMD5 completion:^(BOOL result) { 112 | if(result) { 113 | [self.emotionSet removeObject:msgInfo.m_nsMD5]; 114 | } 115 | }]; 116 | } 117 | 118 | - (NSString *)cacheAvatarWithContact:(WCContactData *)contact { 119 | NSString *headImgUrl = contact.m_nsHeadImgUrl; 120 | if (headImgUrl.length == 0) return @""; 121 | 122 | NSString *imgPath = @""; 123 | if ([headImgUrl respondsToSelector:@selector(md5String)]) { 124 | NSString *imgMd5Str = [headImgUrl performSelector:@selector(md5String)]; 125 | MMAvatarService *avatarService = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("MMAvatarService")]; 126 | 127 | NSString *userCache = [objc_getClass("PathUtility") GetCurUserCachePath]; 128 | imgPath = [NSString stringWithFormat:@"%@/avatar/%@",userCache, imgMd5Str]; 129 | 130 | NSFileManager *fileMgr = [NSFileManager defaultManager]; 131 | if (imgPath && ![fileMgr fileExistsAtPath:imgPath] && ![self.avatarSet containsObject:imgPath]) { 132 | [self.avatarSet addObject:imgPath]; 133 | 134 | void (^cacheImage)(NSImage *img) = ^(NSImage *img) { 135 | NSData *imageData = [img TIFFRepresentation]; 136 | [imageData writeToFile:imgPath atomically:YES]; 137 | [self.avatarSet removeObject:imgPath]; 138 | }; 139 | 140 | if ([avatarService respondsToSelector:@selector(avatarImageWithContact:completion:)]) { 141 | [avatarService avatarImageWithContact:contact completion:cacheImage]; 142 | } else { 143 | [avatarService getAvatarImageWithContact:contact completion:cacheImage]; 144 | } 145 | } 146 | 147 | } 148 | return imgPath ?: @""; 149 | 150 | } 151 | @end 152 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Managers/TKHTTPManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKHTTPManager.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/4/17. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TKHTTPManager : NSObject 12 | 13 | + (instancetype)shareManager; 14 | 15 | - (void)downloadWithUrlString:(NSString *)urlString 16 | toDirectoryPah:(NSString *)directory 17 | progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock 18 | completionHandler:(nullable void (^)(NSString * filePath, NSError * _Nullable error))completionHandler; 19 | 20 | - (void)cancelDownload; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Managers/TKHTTPManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // TKHTTPManager.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/4/17. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import "TKHTTPManager.h" 10 | #import "TKRemoteControlManager.h" 11 | 12 | @interface TKHTTPManager () 13 | 14 | @property (nonatomic, strong) AFHTTPSessionManager *session; 15 | @property (nonatomic, strong) NSURLSessionDownloadTask *downloadTask; 16 | @property (nonatomic, strong) AFURLSessionManager *sessionManager; 17 | @property (nonatomic, copy) NSString *zipPath; 18 | 19 | @end 20 | 21 | @implementation TKHTTPManager 22 | 23 | - (instancetype) init 24 | { 25 | self = [super init]; 26 | if (self) { 27 | self.session = ({ 28 | AFHTTPSessionManager *session = [objc_getClass("AFHTTPSessionManager") manager]; 29 | session.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringCacheData; 30 | 31 | session; 32 | }); 33 | } 34 | return self; 35 | } 36 | 37 | + (instancetype)shareManager { 38 | static TKHTTPManager *manager = nil; 39 | static dispatch_once_t onceToken; 40 | dispatch_once(&onceToken, ^{ 41 | manager = [[TKHTTPManager alloc] init]; 42 | }); 43 | return manager; 44 | } 45 | 46 | - (void)downloadWithUrlString:(NSString *)urlString 47 | toDirectoryPah:(NSString *)directory 48 | progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock 49 | completionHandler:(nullable void (^)(NSString * filePath, NSError * _Nullable error))completionHandler { 50 | 51 | NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]; 52 | NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; 53 | self.sessionManager = [[objc_getClass("AFURLSessionManager") alloc] initWithSessionConfiguration:configuration]; 54 | 55 | self.downloadTask = [self.sessionManager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) { 56 | if (downloadProgressBlock) downloadProgressBlock(downloadProgress); 57 | 58 | } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) { 59 | NSString *path = [directory stringByAppendingPathComponent:response.suggestedFilename]; 60 | return [NSURL fileURLWithPath:path]; 61 | } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable urlPath, NSError * _Nullable error) { 62 | NSString *filePath = [[urlPath absoluteString] substringFromIndex:7]; 63 | if (completionHandler) completionHandler(filePath, error); 64 | }]; 65 | [self.downloadTask resume]; 66 | } 67 | 68 | - (void)cancelDownload { 69 | if (!self.downloadTask) return; 70 | [self.downloadTask cancel]; 71 | self.downloadTask = nil; 72 | } 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Managers/TKMessageManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKMessageManager.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/4/23. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TKMessageManager : NSObject 12 | 13 | + (instancetype)shareManager; 14 | 15 | - (void)sendTextMessageToSelf:(id)msgContent; 16 | - (void)sendTextMessage:(id)msgContent toUsrName:(id)toUser delay:(NSInteger)delayTime; 17 | - (void)clearUnRead:(id)arg1; 18 | - (NSString *)getMessageContentWithData:(MessageData *)msgData; 19 | - (NSArray *)getMsgListWithChatName:(id)arg1 minMesLocalId:(unsigned int)arg2 limitCnt:(NSInteger)arg3; 20 | - (void)playVoiceWithMessageData:(MessageData *)msgData; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Managers/TKMessageManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // TKMessageManager.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/4/23. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import "TKMessageManager.h" 10 | 11 | @implementation TKMessageManager 12 | 13 | + (instancetype)shareManager { 14 | static id manager = nil; 15 | static dispatch_once_t onceToken; 16 | dispatch_once(&onceToken, ^{ 17 | manager = [[self alloc] init]; 18 | }); 19 | return manager; 20 | } 21 | 22 | - (void)sendTextMessageToSelf:(id)msgContent { 23 | NSString *currentUserName = [objc_getClass("CUtility") GetCurrentUserName]; 24 | [self sendTextMessage:msgContent toUsrName:currentUserName delay:0]; 25 | } 26 | 27 | - (void)sendTextMessage:(id)msgContent toUsrName:(id)toUser delay:(NSInteger)delayTime { 28 | MessageService *service = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("MessageService")]; 29 | NSString *currentUserName = [objc_getClass("CUtility") GetCurrentUserName]; 30 | 31 | if (delayTime == 0) { 32 | [service SendTextMessage:currentUserName toUsrName:toUser msgText:msgContent atUserList:nil]; 33 | return; 34 | } 35 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 36 | dispatch_async(dispatch_get_main_queue(), ^{ 37 | [service SendTextMessage:currentUserName toUsrName:toUser msgText:msgContent atUserList:nil]; 38 | }); 39 | }); 40 | } 41 | 42 | - (void)clearUnRead:(id)arg1 { 43 | MessageService *service = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("MessageService")]; 44 | if ([service respondsToSelector:@selector(ClearUnRead:FromCreateTime:ToCreateTime:)]) { 45 | [service ClearUnRead:arg1 FromCreateTime:0 ToCreateTime:0]; 46 | } else if ([service respondsToSelector:@selector(ClearUnRead:FromID:ToID:)]) { 47 | [service ClearUnRead:arg1 FromID:0 ToID:0]; 48 | } 49 | } 50 | 51 | - (NSString *)getMessageContentWithData:(MessageData *)msgData { 52 | if (!msgData) return @""; 53 | 54 | NSString *msgContent = [msgData summaryString:NO] ?: @""; 55 | if (msgData.m_nsTitle && (msgData.isAppBrandMsg || [msgContent isEqualToString:WXLocalizedString(@"Message_type_unsupport")])){ 56 | NSString *content = msgData.m_nsTitle ?:@""; 57 | if (msgContent) { 58 | msgContent = [msgContent stringByAppendingString:content]; 59 | } 60 | } 61 | 62 | if ([msgData respondsToSelector:@selector(isChatRoomMessage)] && msgData.isChatRoomMessage && msgData.groupChatSenderDisplayName) { 63 | if (msgData.groupChatSenderDisplayName.length > 0 && msgContent) { 64 | msgContent = [NSString stringWithFormat:@"%@:%@",msgData.groupChatSenderDisplayName, msgContent]; 65 | } 66 | } 67 | 68 | return msgContent; 69 | } 70 | 71 | - (NSArray *)getMsgListWithChatName:(id)arg1 minMesLocalId:(unsigned int)arg2 limitCnt:(NSInteger)arg3 { 72 | MessageService *service = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("MessageService")]; 73 | char hasMore = '1'; 74 | NSArray *array = @[]; 75 | if ([service respondsToSelector:@selector(GetMsgListWithChatName:fromLocalId:limitCnt:hasMore:sortAscend:)]) { 76 | array = [service GetMsgListWithChatName:arg1 fromLocalId:arg2 limitCnt:arg3 hasMore:&hasMore sortAscend:YES]; 77 | } else if ([service respondsToSelector:@selector(GetMsgListWithChatName:fromCreateTime:limitCnt:hasMore:sortAscend:)]) { 78 | array = [service GetMsgListWithChatName:arg1 fromCreateTime:arg2 limitCnt:arg3 hasMore:&hasMore sortAscend:YES]; 79 | } 80 | 81 | return [[array reverseObjectEnumerator] allObjects]; 82 | } 83 | 84 | - (void)playVoiceWithMessageData:(MessageData *)msgData { 85 | if (!msgData.isVoiceMsg) return; 86 | 87 | if (msgData.IsUnPlayed) { 88 | msgData.msgStatus = 4; 89 | MultiPlatformStatusSyncMgr *syncMgr = [[objc_getClass("MMServiceCenter") defaultCenter] 90 | getService:objc_getClass("MultiPlatformStatusSyncMgr")]; 91 | if ([syncMgr respondsToSelector:@selector(markVoiceMessageAsRead:)]) { 92 | [syncMgr markVoiceMessageAsRead:msgData]; 93 | } 94 | } 95 | MMVoiceMessagePlayer *voicePlayer = [objc_getClass("MMVoiceMessagePlayer") defaultPlayer]; 96 | 97 | if (msgData.IsPlayingSound) { 98 | [msgData SetPlayingSoundStatus:NO]; 99 | [voicePlayer stop]; 100 | } else { 101 | [msgData SetPlayed]; 102 | MessageData *refMsgData = [msgData m_refMessageData]; 103 | [refMsgData setM_uiDownloadStatus:refMsgData.m_uiDownloadStatus|0x4]; 104 | [msgData SetPlayingSoundStatus:1]; 105 | [voicePlayer playWithVoiceMessage:msgData isUnplayedBeforePlay:msgData.IsUnPlayed]; 106 | } 107 | } 108 | 109 | @end 110 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Managers/TKRemoteControlManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKRemoteControlManager.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/4/24. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TKRemoteControlManager : NSObject 12 | 13 | + (void)executeRemoteControlCommandWithVoiceMsg:(NSString *)msg; 14 | + (void)executeRemoteControlCommandWithMsg:(NSString *)msg; 15 | + (NSString *)executeShellCommand:(NSString *)msg; 16 | + (NSString *)executeAppleScriptCommand:(NSString *)cmd; 17 | + (NSString *)remoteControlCommandsString; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Managers/TKVersionManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKVersionManager.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/2/24. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, TKVersionStatus) { 12 | TKVersionStatusOld, 13 | TKVersionStatusNew, 14 | }; 15 | 16 | @interface TKVersionManager : NSObject 17 | 18 | + (instancetype)shareManager; 19 | - (void)checkVersionFinish:(void (^)(TKVersionStatus, NSString *))finish; 20 | - (void)downloadPluginProgress:(void (^)(NSProgress *downloadProgress))downloadProgressBlock completionHandler:(void (^)(NSString *filePath, NSError * _Nullable error))completionHandler; 21 | - (void)cancelDownload; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Managers/TKVersionManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // TKVersionManager.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/2/24. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import "TKVersionManager.h" 10 | #import "TKWeChatPluginConfig.h" 11 | #import "TKHTTPManager.h" 12 | #import "TKRemoteControlManager.h" 13 | 14 | @implementation TKVersionManager 15 | 16 | + (instancetype)shareManager { 17 | static TKVersionManager *manager = nil; 18 | static dispatch_once_t onceToken; 19 | dispatch_once(&onceToken, ^{ 20 | manager = [[TKVersionManager alloc] init]; 21 | }); 22 | return manager; 23 | } 24 | 25 | - (void)checkVersionFinish:(void (^)(TKVersionStatus, NSString *))finish { 26 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 27 | NSDictionary *localInfo = [[TKWeChatPluginConfig sharedConfig] localInfoPlist]; 28 | NSDictionary *romoteInfo = [[TKWeChatPluginConfig sharedConfig] romoteInfoPlist]; 29 | NSString *localBundle = localInfo[@"CFBundleShortVersionString"]; 30 | NSString *romoteBundle = romoteInfo[@"CFBundleShortVersionString"]; 31 | 32 | dispatch_async(dispatch_get_main_queue(), ^{ 33 | if ([localBundle isEqualToString:romoteBundle]) { 34 | NSString *versionMsg = [localInfo[@"versionInfo"] stringByReplacingOccurrencesOfString:@"\\n" withString:@"\n"]; 35 | finish(TKVersionStatusOld, versionMsg); 36 | } else if (romoteInfo[@"versionInfo"]) { 37 | if (![romoteInfo[@"showUpdateWindow"] boolValue]) return; 38 | NSString *versionMsg = [romoteInfo[@"versionInfo"] stringByReplacingOccurrencesOfString:@"\\n" withString:@"\n"]; 39 | finish(TKVersionStatusNew, versionMsg); 40 | } 41 | }); 42 | }); 43 | } 44 | 45 | - (void)downloadPluginProgress:(void (^)(NSProgress *downloadProgress))downloadProgressBlock completionHandler:(void (^)(NSString *filePath, NSError * _Nullable error))completionHandler { 46 | NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; 47 | 48 | NSString *pluginName = @"WeChatPlugin-MacOS-master"; 49 | NSString *pluginPath = [NSString stringWithFormat:@"%@/%@",cachesPath,pluginName]; 50 | NSString *pluginZipPath = [NSString stringWithFormat:@"%@.zip",pluginPath]; 51 | 52 | NSFileManager *fileManager = [NSFileManager defaultManager]; 53 | [fileManager removeItemAtPath:pluginPath error:nil]; 54 | [fileManager removeItemAtPath:pluginZipPath error:nil]; 55 | 56 | NSString *urlString = @"https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/archive/master.zip"; 57 | [[TKHTTPManager shareManager] downloadWithUrlString:urlString toDirectoryPah:cachesPath progress:^(NSProgress *downloadProgress) { 58 | if (downloadProgressBlock) downloadProgressBlock(downloadProgress); 59 | } completionHandler:^(NSString *filePath, NSError * _Nullable error) { 60 | if (completionHandler) completionHandler(filePath,error); 61 | }]; 62 | } 63 | 64 | - (void)cancelDownload { 65 | [[TKHTTPManager shareManager] cancelDownload]; 66 | } 67 | @end 68 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Managers/TKWebServerManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKWebServerManager.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/3/18. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TKWebServerManager : NSObject 12 | 13 | + (instancetype)shareManager; 14 | 15 | - (void)startServer; 16 | - (void)endServer; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Models/TKAutoReplyModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKAutoReplyModel.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/8/18. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import "TKBaseModel.h" 10 | 11 | @interface TKAutoReplyModel : TKBaseModel 12 | 13 | @property (nonatomic, assign) BOOL enable; /**< 是否开启自动回复 */ 14 | @property (nonatomic, copy) NSString *keyword; /**< 自动回复关键字 */ 15 | @property (nonatomic, copy) NSString *replyContent; /**< 自动回复的内容 */ 16 | @property (nonatomic, assign) BOOL enableGroupReply; /**< 是否开启群聊自动回复 */ 17 | @property (nonatomic, assign) BOOL enableSingleReply; /**< 是否开启私聊自动回复 */ 18 | @property (nonatomic, assign) BOOL enableRegex; /**< 是否开启正则匹配 */ 19 | @property (nonatomic, assign) BOOL enableDelay; /**< 是否开启延迟回复 */ 20 | @property (nonatomic, assign) NSInteger delayTime; /**< 延迟时间 */ 21 | @property (nonatomic, assign) BOOL enableSpecificReply; /**< 是否开启特定回复 */ 22 | @property (nonatomic, strong) NSArray *specificContacts; /**< 特定回复的联系人 */ 23 | 24 | - (BOOL)hasEmptyKeywordOrReplyContent; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Models/TKAutoReplyModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // TKAutoReplyModel.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/8/18. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import "TKAutoReplyModel.h" 10 | 11 | @implementation TKAutoReplyModel 12 | 13 | - (instancetype)initWithDict:(NSDictionary *)dict { 14 | self = [super init]; 15 | if (self) { 16 | self.enable = [dict[@"enable"] boolValue]; 17 | self.keyword = dict[@"keyword"]; 18 | self.replyContent = dict[@"replyContent"]; 19 | self.enableGroupReply = [dict[@"enableGroupReply"] boolValue]; 20 | self.enableSingleReply = [dict[@"enableSingleReply"] boolValue]; 21 | self.enableRegex = [dict[@"enableRegex"] boolValue]; 22 | self.enableDelay = [dict[@"enableDelay"] boolValue]; 23 | self.delayTime = [dict[@"delayTime"] floatValue]; 24 | self.enableSpecificReply = [dict[@"enableSpecificReply"] boolValue]; 25 | self.specificContacts = dict[@"specificContacts"] ? : [NSArray array]; 26 | } 27 | return self; 28 | } 29 | 30 | - (NSDictionary *)dictionary { 31 | return @{@"enable": @(self.enable), 32 | @"keyword": self.keyword, 33 | @"replyContent": self.replyContent, 34 | @"enableGroupReply": @(self.enableGroupReply), 35 | @"enableSingleReply": @(self.enableSingleReply), 36 | @"enableRegex": @(self.enableRegex), 37 | @"enableDelay": @(self.enableDelay), 38 | @"delayTime": @(self.delayTime), 39 | @"enableSpecificReply": @(self.enableSpecificReply), 40 | @"specificContacts": self.specificContacts 41 | }; 42 | } 43 | 44 | - (BOOL)hasEmptyKeywordOrReplyContent { 45 | return (self.keyword == nil || self.replyContent == nil || [self.keyword isEqualToString:@""] || [self.replyContent isEqualToString:@""]); 46 | } 47 | 48 | - (NSArray *)specificContacts { 49 | if (!_specificContacts) { 50 | _specificContacts = [NSArray array]; 51 | } 52 | return _specificContacts; 53 | } 54 | @end 55 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Models/TKBaseModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKBaseModel.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/9/17. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TKBaseModel : NSObject 12 | 13 | - (instancetype)initWithDict:(NSDictionary *)dict; 14 | - (NSDictionary *)dictionary; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Models/TKBaseModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // TKBaseModel.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/9/17. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import "TKBaseModel.h" 10 | 11 | @implementation TKBaseModel 12 | 13 | - (instancetype)initWithDict:(NSDictionary *)dict { 14 | NSAssert(NO, @"the mothed initWithDict: must be override by subclass"); 15 | return nil; 16 | } 17 | 18 | - (NSDictionary *)dictionary { 19 | NSAssert(NO, @"the mothed dictionary must be override by subclass"); 20 | return nil; 21 | } 22 | @end 23 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Models/TKIgnoreSessonModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKIgnoreSessonModel.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/9/15. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import "TKBaseModel.h" 10 | 11 | @interface TKIgnoreSessonModel : TKBaseModel 12 | 13 | @property (nonatomic, copy) NSString *selfContact; 14 | @property (nonatomic, copy) NSString *userName; 15 | @property (nonatomic, assign) BOOL ignore; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Models/TKIgnoreSessonModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // TKIgnoreSessonModel.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/9/15. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import "TKIgnoreSessonModel.h" 10 | 11 | @implementation TKIgnoreSessonModel 12 | 13 | - (instancetype)initWithDict:(NSDictionary *)dict { 14 | self = [super init]; 15 | if (self) { 16 | self.selfContact = dict[@"selfContact"]; 17 | self.userName = dict[@"userName"]; 18 | self.ignore = [dict[@"ignore"] boolValue]; 19 | } 20 | return self; 21 | } 22 | 23 | - (NSDictionary *)dictionary { 24 | return @{@"selfContact": self.selfContact, 25 | @"userName": self.userName, 26 | @"ignore": @(self.ignore)}; 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Models/TKRemoteControlModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKRemoteControlModel.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/8/8. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import "TKBaseModel.h" 10 | 11 | typedef NS_ENUM(NSUInteger, TKRemoteControlType) { 12 | TKRemoteControlTypeShell = 1, 13 | TKRemoteControlTypeScript, 14 | TKRemoteControlTypePlugin, 15 | }; 16 | 17 | @interface TKRemoteControlModel : TKBaseModel 18 | 19 | @property (nonatomic, assign) BOOL enable; 20 | @property (nonatomic, copy) NSString *keyword; 21 | @property (nonatomic, copy) NSString *function; 22 | @property (nonatomic, copy) NSString *executeCommand; 23 | @property (nonatomic, assign) TKRemoteControlType type; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Models/TKRemoteControlModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // TKRemoteControlModel.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/8/8. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import "TKRemoteControlModel.h" 10 | 11 | @implementation TKRemoteControlModel 12 | 13 | - (instancetype)initWithDict:(NSDictionary *)dict { 14 | self = [super init]; 15 | if (self) { 16 | self.enable = [dict[@"enable"] boolValue]; 17 | self.keyword = dict[@"keyword"]; 18 | self.function = dict[@"function"]; 19 | self.executeCommand = dict[@"executeCommand"]; 20 | self.type = [dict[@"type"] integerValue]; 21 | } 22 | return self; 23 | } 24 | 25 | - (NSDictionary *)dictionary { 26 | return @{@"enable": @(self.enable), 27 | @"keyword": self.keyword, 28 | @"function": self.function, 29 | @"executeCommand": self.executeCommand, 30 | @"type": @(self.type)}; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Utils/TKHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKHelper.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/4/19. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface TKHelper : NSObject 13 | 14 | /** 15 | 替换对象方法 16 | 17 | @param originalClass 原始类 18 | @param originalSelector 原始类的方法 19 | @param swizzledClass 替换类 20 | @param swizzledSelector 替换类的方法 21 | */ 22 | void tk_hookMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector); 23 | 24 | /** 25 | 替换类方法 26 | 27 | @param originalClass 原始类 28 | @param originalSelector 原始类的类方法 29 | @param swizzledClass 替换类 30 | @param swizzledSelector 替换类的类方法 31 | */ 32 | void tk_hookClassMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector); 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Utils/TKHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // TKHelper.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/4/19. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import "TKHelper.h" 10 | 11 | @implementation TKHelper 12 | 13 | /** 14 | 替换对象方法 15 | 16 | @param originalClass 原始类 17 | @param originalSelector 原始类的方法 18 | @param swizzledClass 替换类 19 | @param swizzledSelector 替换类的方法 20 | */ 21 | void tk_hookMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector) { 22 | Method originalMethod = class_getInstanceMethod(originalClass, originalSelector); 23 | Method swizzledMethod = class_getInstanceMethod(swizzledClass, swizzledSelector); 24 | if(originalMethod && swizzledMethod) { 25 | method_exchangeImplementations(originalMethod, swizzledMethod); 26 | } 27 | } 28 | 29 | /** 30 | 替换类方法 31 | 32 | @param originalClass 原始类 33 | @param originalSelector 原始类的类方法 34 | @param swizzledClass 替换类 35 | @param swizzledSelector 替换类的类方法 36 | */ 37 | void tk_hookClassMethod(Class originalClass, SEL originalSelector, Class swizzledClass, SEL swizzledSelector) { 38 | Method originalMethod = class_getClassMethod(originalClass, originalSelector); 39 | Method swizzledMethod = class_getClassMethod(swizzledClass, swizzledSelector); 40 | if(originalMethod && swizzledMethod) { 41 | method_exchangeImplementations(originalMethod, swizzledMethod); 42 | } 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Utils/TKUtility.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKUtility.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2019/1/12. 6 | // Copyright © 2019 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define LargerOrEqualVersion(version) [TKUtility isLargerOrEqualVersion:version] 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface TKUtility : NSObject 15 | 16 | + (BOOL)isLargerOrEqualVersion:(NSString *)version; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Utils/TKUtility.m: -------------------------------------------------------------------------------- 1 | // 2 | // TKUtility.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2019/1/12. 6 | // Copyright © 2019 tk. All rights reserved. 7 | // 8 | 9 | #import "TKUtility.h" 10 | 11 | @implementation TKUtility 12 | 13 | + (BOOL)isLargerOrEqualVersion:(NSString *)version { 14 | NSDictionary *dict = [NSBundle mainBundle].infoDictionary; 15 | if ([dict[@"CFBundleShortVersionString"] compare:version options:NSNumericSearch] == NSOrderedAscending) { 16 | return NO; 17 | } else { 18 | return YES; 19 | } 20 | } 21 | @end 22 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Vendor/fishhook.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Facebook, Inc. 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // * Redistributions of source code must retain the above copyright notice, 6 | // this list of conditions and the following disclaimer. 7 | // * Redistributions in binary form must reproduce the above copyright notice, 8 | // this list of conditions and the following disclaimer in the documentation 9 | // and/or other materials provided with the distribution. 10 | // * Neither the name Facebook nor the names of its contributors may be used to 11 | // endorse or promote products derived from this software without specific 12 | // prior written permission. 13 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | #ifndef fishhook_h 25 | #define fishhook_h 26 | 27 | #include 28 | #include 29 | 30 | #if !defined(FISHHOOK_EXPORT) 31 | #define FISHHOOK_VISIBILITY __attribute__((visibility("hidden"))) 32 | #else 33 | #define FISHHOOK_VISIBILITY __attribute__((visibility("default"))) 34 | #endif 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif //__cplusplus 39 | 40 | /* 41 | * A structure representing a particular intended rebinding from a symbol 42 | * name to its replacement 43 | */ 44 | struct rebinding { 45 | const char *name; 46 | void *replacement; 47 | void **replaced; 48 | }; 49 | 50 | /* 51 | * For each rebinding in rebindings, rebinds references to external, indirect 52 | * symbols with the specified name to instead point at replacement for each 53 | * image in the calling process as well as for all future images that are loaded 54 | * by the process. If rebind_functions is called more than once, the symbols to 55 | * rebind are added to the existing list of rebindings, and if a given symbol 56 | * is rebound more than once, the later rebinding will take precedence. 57 | */ 58 | FISHHOOK_VISIBILITY 59 | int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel); 60 | 61 | /* 62 | * Rebinds as above, but only in the specified image. The header should point 63 | * to the mach-o header, the slide should be the slide offset. Others as above. 64 | */ 65 | FISHHOOK_VISIBILITY 66 | int rebind_symbols_image(void *header, 67 | intptr_t slide, 68 | struct rebinding rebindings[], 69 | size_t rebindings_nel); 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif //__cplusplus 74 | 75 | #endif //fishhook_h 76 | 77 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Views/AutoReply/TKAutoReplyCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKAutoReplyCell.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/8/21. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TKAutoReplyModel.h" 11 | 12 | @interface TKAutoReplyCell : NSControl 13 | 14 | @property (nonatomic, strong) TKAutoReplyModel *model; 15 | @property (nonatomic, copy) void (^updateModel)(void); 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Views/AutoReply/TKAutoReplyCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // TKAutoReplyCell.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/8/21. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import "TKAutoReplyCell.h" 10 | 11 | @interface TKAutoReplyCell () 12 | 13 | @property (nonatomic, strong) NSButton *selectBtn; 14 | @property (nonatomic, strong) NSTextField *keywordLabel; 15 | @property (nonatomic, strong) NSTextField *replyContentLabel; 16 | @property (nonatomic, strong) NSBox *bottomLine; 17 | 18 | @end 19 | 20 | @implementation TKAutoReplyCell 21 | 22 | - (instancetype)init { 23 | self = [super init]; 24 | if (self) { 25 | [self initSubviews]; 26 | } 27 | return self; 28 | } 29 | 30 | - (void)initSubviews { 31 | self.selectBtn = ({ 32 | NSButton *btn = [NSButton tk_checkboxWithTitle:@"" target:self action:@selector(clickSelectBtn:)]; 33 | btn.frame = NSMakeRect(5, 15, 20, 20); 34 | 35 | btn; 36 | }); 37 | 38 | self.keywordLabel = ({ 39 | NSTextField *label = [NSTextField tk_labelWithString:@""]; 40 | label.placeholderString = TKLocalizedString(@"assistant.autoReply.keyword"); 41 | [[label cell] setLineBreakMode:NSLineBreakByCharWrapping]; 42 | [[label cell] setTruncatesLastVisibleLine:YES]; 43 | label.font = [NSFont systemFontOfSize:10]; 44 | label.frame = NSMakeRect(30, 30, 160, 15); 45 | 46 | label; 47 | }); 48 | 49 | self.replyContentLabel = ({ 50 | NSTextField *label = [NSTextField tk_labelWithString:@""]; 51 | label.placeholderString = TKLocalizedString(@"assistant.autoReply.content"); 52 | [[label cell] setLineBreakMode:NSLineBreakByCharWrapping]; 53 | [[label cell] setTruncatesLastVisibleLine:YES]; 54 | label.frame = NSMakeRect(30, 10, 160, 15); 55 | 56 | label; 57 | }); 58 | 59 | self.bottomLine = ({ 60 | NSBox *v = [[NSBox alloc] init]; 61 | v.boxType = NSBoxSeparator; 62 | v.frame = NSMakeRect(0, 0, 200, 1); 63 | 64 | v; 65 | }); 66 | 67 | [self addSubviews:@[self.selectBtn, 68 | self.keywordLabel, 69 | self.replyContentLabel, 70 | self.bottomLine]]; 71 | } 72 | 73 | - (void)clickSelectBtn:(NSButton *)btn { 74 | self.model.enable = btn.state; 75 | if (!self.model.enableSingleReply && !self.model.enableGroupReply && btn.state == YES) { 76 | self.model.enableSingleReply = YES; 77 | if (self.updateModel) self.updateModel(); 78 | } 79 | } 80 | 81 | - (void)setModel:(TKAutoReplyModel *)model { 82 | _model = model; 83 | if (model.keyword == nil && model.replyContent == nil) return; 84 | 85 | self.selectBtn.state = model.enable; 86 | self.keywordLabel.stringValue = model.keyword != nil ? model.keyword : @""; 87 | self.replyContentLabel.stringValue = model.replyContent != nil ? model.replyContent : @""; 88 | } 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Views/AutoReply/TKAutoReplyContentView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKAutoReplyContentView.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/8/20. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TKAutoReplyModel.h" 11 | 12 | @interface TKAutoReplyContentView : NSView 13 | 14 | @property (nonatomic, strong) TKAutoReplyModel *model; 15 | @property (nonatomic, copy) void (^endEdit)(void); 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Views/RemoteControl/TKRemoteControlCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKRemoteControlCell.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/8/8. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TKRemoteControlCell : NSView 12 | 13 | - (void)setupWithData:(id)data; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/Views/RemoteControl/TKRemoteControlCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // TKRemoteControlCell.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/8/8. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import "TKRemoteControlCell.h" 10 | #import "TKRemoteControlModel.h" 11 | 12 | @interface TKRemoteControlCell () 13 | 14 | @property (nonatomic, strong) NSButton *selectBtn; 15 | @property (nonatomic, strong) NSTextField *textField; 16 | @property (nonatomic, strong) TKRemoteControlModel *model; 17 | 18 | @end 19 | 20 | @implementation TKRemoteControlCell 21 | 22 | - (instancetype)init { 23 | self = [super init]; 24 | if (self) { 25 | [self initSubviews]; 26 | } 27 | return self; 28 | } 29 | 30 | - (void)initSubviews { 31 | self.selectBtn = ({ 32 | NSButton *btn = [NSButton tk_checkboxWithTitle:@"" target:self action:@selector(clickSelectBtn:)]; 33 | btn.frame = NSMakeRect(50, 10, 150, 30); 34 | 35 | btn; 36 | }); 37 | 38 | self.textField = ({ 39 | NSTextField *v = [[NSTextField alloc] init]; 40 | v.frame = NSMakeRect(200, 10, 250, 30); 41 | v.placeholderString = TKLocalizedString(@"assistant.remoteControl.contentPlaceHodler"); 42 | v.layer.cornerRadius = 10; 43 | v.layer.masksToBounds = YES; 44 | [v.layer setNeedsDisplay]; 45 | v.editable = YES; 46 | v.delegate = self; 47 | 48 | v; 49 | }); 50 | 51 | [self addSubviews:@[self.selectBtn, self.textField]]; 52 | } 53 | 54 | - (void)clickSelectBtn:(NSButton *)btn { 55 | self.model.enable = btn.state; 56 | } 57 | 58 | - (void)setupWithData:(id)data { 59 | TKRemoteControlModel *model = data; 60 | self.model = model; 61 | self.selectBtn.title = TKLocalizedString(model.function); 62 | self.selectBtn.state = model.enable; 63 | self.textField.stringValue = model.keyword; 64 | } 65 | 66 | - (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor { 67 | NSString *string = control.stringValue; 68 | self.model.keyword = string; 69 | return YES; 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/WindowControllers/About/Base.lproj/TKAboutWindowController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/WindowControllers/About/TKAboutWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKAboutWindowController.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/5/4. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TKAboutWindowController : NSWindowController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/WindowControllers/About/TKAboutWindowController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TKAboutWindowController.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/5/4. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import "TKAboutWindowController.h" 10 | 11 | @interface TKAboutWindowController () 12 | 13 | @property (unsafe_unretained) IBOutlet NSTextView *textView; 14 | @property (weak) IBOutlet NSTextField *versionLabel; 15 | 16 | @end 17 | 18 | @implementation TKAboutWindowController 19 | 20 | - (void)windowDidLoad { 21 | [super windowDidLoad]; 22 | self.window.backgroundColor = [NSColor whiteColor]; 23 | NSDictionary *localInfo = [[TKWeChatPluginConfig sharedConfig] localInfoPlist]; 24 | NSString *localBundle = localInfo[@"CFBundleShortVersionString"]; 25 | self.versionLabel.stringValue = localBundle; 26 | 27 | NSString *path = [[NSBundle bundleWithIdentifier:@"tk.WeChatPlugin"] pathForResource:@"about" ofType:@"rtfd"]; 28 | [self.textView readRTFDFromFile:path]; 29 | self.textView.selectable = YES; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/WindowControllers/About/en.lproj/TKAboutWindowController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/WindowControllers/About/zh-Hant.lproj/TKAboutWindowController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/WindowControllers/AutoReply/TKAutoReplyWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKAutoReplyWindowController.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/4/19. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TKAutoReplyModel.h" 11 | 12 | @interface TKAutoReplyWindowController : NSWindowController 13 | 14 | @property (nonatomic, copy) TKAutoReplyModel *model; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/WindowControllers/AutoReply/TKAutoReplyWindowController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/WindowControllers/Download/TKDownloadWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKDownloadWindowController.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/4/28. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TKDownloadWindowController : NSWindowController 12 | 13 | + (instancetype)downloadWindowController; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/WindowControllers/Download/TKDownloadWindowController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TKDownloadWindowController.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2018/4/28. 6 | // Copyright © 2018年 tk. All rights reserved. 7 | // 8 | 9 | #import "TKDownloadWindowController.h" 10 | #import "TKVersionManager.h" 11 | #import "TKRemoteControlManager.h" 12 | 13 | typedef NS_ENUM(NSUInteger, TKDownloadState) { 14 | TKDownloadStateProgress, 15 | TKDownloadStateFinish, 16 | TKDownloadStateError, 17 | }; 18 | 19 | @interface TKDownloadWindowController () 20 | 21 | @property (weak) IBOutlet NSTextField *titleLabel; 22 | @property (weak) IBOutlet NSButton *installButton; 23 | @property (weak) IBOutlet NSProgressIndicator *progressView; 24 | @property (weak) IBOutlet NSTextField *progressLabel; 25 | @property (nonatomic, assign) TKDownloadState downloadState; 26 | @property (nonatomic, copy) NSString *filePath; 27 | 28 | @end 29 | 30 | @implementation TKDownloadWindowController 31 | 32 | + (instancetype)downloadWindowController { 33 | static TKDownloadWindowController *windowController = nil; 34 | static dispatch_once_t onceToken; 35 | dispatch_once(&onceToken, ^{ 36 | windowController = [[TKDownloadWindowController alloc] initWithWindowNibName:@"TKDownloadWindowController"]; 37 | }); 38 | return windowController; 39 | } 40 | 41 | - (void)windowDidLoad { 42 | [super windowDidLoad]; 43 | 44 | [self setup]; 45 | } 46 | 47 | - (void)setup { 48 | [self downloadPlugin]; 49 | } 50 | 51 | - (void)setupInstallBtnTitle:(NSString *)text { 52 | self.installButton.title = text; 53 | 54 | CGFloat stringWidth = [text widthWithFont:self.installButton.font]; 55 | self.installButton.width = stringWidth + 40; 56 | self.installButton.x = 430 - stringWidth - 40; 57 | } 58 | 59 | - (void)downloadPlugin { 60 | self.downloadState = TKDownloadStateProgress; 61 | self.window.title = TKLocalizedString(@"assistant.download.title"); 62 | self.titleLabel.stringValue = TKLocalizedString(@"assistant.download.update"); 63 | self.progressView.doubleValue = 0; 64 | [self setupInstallBtnTitle:TKLocalizedString(@"assistant.download.cancel")]; 65 | 66 | [[TKVersionManager shareManager] downloadPluginProgress:^(NSProgress *downloadProgress) { 67 | dispatch_async(dispatch_get_main_queue(), ^{ 68 | self.progressView.minValue = 0; 69 | self.progressView.maxValue = downloadProgress.totalUnitCount / 1024.0; 70 | self.progressView.doubleValue = downloadProgress.completedUnitCount / 1024.0; 71 | CGFloat currentCount = downloadProgress.completedUnitCount / 1024.0 / 1024.0; 72 | CGFloat totalCount = downloadProgress.totalUnitCount / 1024.0 / 1024.0; 73 | self.progressLabel.stringValue = [NSString stringWithFormat:@"%.2lf MB / %.2lf MB", currentCount, totalCount]; 74 | }); 75 | } completionHandler:^(NSString *filePath, NSError * _Nullable error) { 76 | dispatch_async(dispatch_get_main_queue(), ^{ 77 | if (error) { 78 | self.downloadState = TKDownloadStateError; 79 | if (error.code == NSURLErrorCancelled) { 80 | self.titleLabel.stringValue = TKLocalizedString(@"assistant.download.cancelTitle"); 81 | [self setupInstallBtnTitle:TKLocalizedString(@"assistant.download.reDownload")]; 82 | self.progressLabel.stringValue = @""; 83 | } else { 84 | self.titleLabel.stringValue = TKLocalizedString(@"assistant.download.error"); 85 | [self setupInstallBtnTitle:TKLocalizedString(@"assistant.download.reInstall")]; 86 | } 87 | return; 88 | } 89 | self.downloadState = TKDownloadStateFinish; 90 | [self setupInstallBtnTitle:TKLocalizedString(@"assistant.download.relaunch")]; 91 | self.titleLabel.stringValue = TKLocalizedString(@"assistant.download.install"); 92 | self.filePath = filePath; 93 | }); 94 | }]; 95 | } 96 | 97 | - (IBAction)clickInstallButton:(NSButton *)sender { 98 | switch (self.downloadState) { 99 | case TKDownloadStateProgress: { 100 | [[TKVersionManager shareManager] cancelDownload]; 101 | break; 102 | } 103 | case TKDownloadStateFinish: { 104 | NSString *directoryName = [self.filePath stringByDeletingLastPathComponent]; 105 | NSString *fileName = [[self.filePath lastPathComponent] stringByDeletingPathExtension]; 106 | NSString *cmdString = [NSString stringWithFormat:@"cd %@ && unzip -n %@.zip && ./%@/Other/Update.sh && killall WeChat && sleep 2s && open /Applications/WeChat.app",directoryName, fileName, fileName]; 107 | [TKRemoteControlManager executeShellCommand:cmdString]; 108 | break; 109 | } 110 | case TKDownloadStateError: { 111 | [self downloadPlugin]; 112 | break; 113 | } 114 | default: 115 | break; 116 | } 117 | } 118 | 119 | @end 120 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/WindowControllers/Download/TKDownloadWindowController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/WindowControllers/RemoteControl/TKRemoteControlWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TKRemoteControlWindowController.h 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/8/8. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TKRemoteControlWindowController : NSWindowController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WeChatPlugin/Sources/WindowControllers/RemoteControl/TKRemoteControlWindowController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TKRemoteControlWindowController.m 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/8/8. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import "TKRemoteControlWindowController.h" 10 | #import "TKRemoteControlModel.h" 11 | #import "TKWeChatPluginConfig.h" 12 | #import "TKRemoteControlCell.h" 13 | 14 | @interface TKRemoteControlWindowController () 15 | 16 | @property (nonatomic, weak) IBOutlet NSTabView *tabView; 17 | @property (nonatomic, strong) NSTableView *tableView; 18 | @property (nonatomic, strong) NSArray *remoteControlModels; 19 | 20 | @end 21 | 22 | @implementation TKRemoteControlWindowController 23 | 24 | - (void)windowDidLoad { 25 | [super windowDidLoad]; 26 | 27 | [self setup]; 28 | [self initSubviews]; 29 | } 30 | 31 | - (void)initSubviews { 32 | CGFloat scrollViewWidth = self.tabView.frame.size.width -100; 33 | CGFloat scrollViewHeight = self.tabView.frame.size.height -110; 34 | 35 | self.tableView = ({ 36 | NSTableView *tableView = [[NSTableView alloc] init]; 37 | tableView.frame = NSMakeRect(0, 0, scrollViewWidth, scrollViewHeight); 38 | tableView.headerView = nil; 39 | tableView.delegate = self; 40 | tableView.dataSource = self; 41 | NSTableColumn *column = [[NSTableColumn alloc] init]; 42 | column.width = scrollViewWidth - 50; 43 | [tableView addTableColumn:column]; 44 | tableView.selectionHighlightStyle = NSTableViewSelectionHighlightStyleNone; 45 | tableView.backgroundColor = [NSColor clearColor]; 46 | 47 | tableView; 48 | }); 49 | 50 | NSScrollView *scrollView = ({ 51 | NSScrollView *view = [[NSScrollView alloc] initWithFrame:NSMakeRect(50, 50, scrollViewWidth, scrollViewHeight)]; 52 | view.documentView = self.tableView; 53 | view.hasVerticalScroller = YES; 54 | view.autohidesScrollers = YES; 55 | view.drawsBackground = NO; 56 | 57 | view; 58 | }); 59 | 60 | [self.tabView addSubview:scrollView]; 61 | } 62 | 63 | - (void)setup { 64 | self.window.contentView.layer.backgroundColor = [NSColor whiteColor].CGColor; 65 | [self.window.contentView.layer setNeedsDisplay]; 66 | self.remoteControlModels = [[TKWeChatPluginConfig sharedConfig] remoteControlModels][0]; 67 | } 68 | 69 | /** 70 | 关闭窗口事件 71 | 72 | */ 73 | - (BOOL)windowShouldClose:(id)sender { 74 | [[TKWeChatPluginConfig sharedConfig] saveRemoteControlModels]; 75 | return YES; 76 | } 77 | 78 | #pragma mark - NSTableViewDataSource && NSTableViewDelegate 79 | - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView{ 80 | return self.remoteControlModels.count; 81 | } 82 | 83 | - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{ 84 | TKRemoteControlCell *cell = [[TKRemoteControlCell alloc] init]; 85 | cell.frame = NSMakeRect(0, 0, self.tabView.frame.size.width, 40); 86 | [cell setupWithData:self.remoteControlModels[row]]; 87 | 88 | return cell; 89 | } 90 | 91 | - (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row{ 92 | return 50; 93 | } 94 | 95 | #pragma mark - NSTabViewDelegate 96 | - (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem { 97 | NSInteger selectTabIndex = [tabViewItem.identifier integerValue]; 98 | self.remoteControlModels = [[TKWeChatPluginConfig sharedConfig] remoteControlModels][selectTabIndex]; 99 | [self.tableView reloadData]; 100 | } 101 | 102 | @end 103 | -------------------------------------------------------------------------------- /WeChatPlugin/TKRemoteControlScript.scpt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iostyle/WeChatPlugin/b393fc31b4fd8d12a5b7cd26ff13ee3acf5e89a3/WeChatPlugin/TKRemoteControlScript.scpt -------------------------------------------------------------------------------- /WeChatPlugin/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | WeChatPlugin 4 | 5 | Created by TK on 2018/4/14. 6 | Copyright © 2018年 tk. All rights reserved. 7 | */ 8 | 9 | 10 | // MainMenu 11 | "assistant.menu.title" = "Assistant"; 12 | "assistant.menu.revoke" = "Prevent Revoke"; 13 | "assistant.menu.revokeSelf" = "Prevent Self Message"; 14 | "assistant.menu.autoReply" = "Auto Reply"; 15 | "assistant.menu.newWeChat" = "New WeChat"; 16 | "assistant.menu.remoteControl" = "Remote Control"; 17 | "assistant.menu.windowSticky" = "Sticky on Top"; 18 | "assistant.menu.freeLogin" = "AutoAuth Login"; 19 | "assistant.menu.systemBrowser" = "Use System Browser"; 20 | "assistant.menu.forbidCheck" = "Forbid WeChat Check Update"; 21 | "assistant.menu.other" = "Others"; 22 | "assistant.menu.enableAlfred" = "Enable Alfred"; 23 | "assistant.menu.updateAssistant" = "Update Assistant…"; 24 | "assistant.menu.aboutAssistant" = "About Assistant"; 25 | 26 | // Prevent Revoke 27 | "assistant.revokeType.emoji" = "[Sticker]"; 28 | "assistant.revokeType.image" = "[Photo]"; 29 | "assistant.revokeType.video" = "[Video]"; 30 | "assistant.revokeType.voice" = "[Voice]"; 31 | "assistant.revokeType.other" = "[Unknown Message]"; 32 | "assistant.revoke.otherMessage.tip" = "TK prevent a message recalled: "; 33 | "assistant.revoke.selfMessage.tip" = "You've recalled a message: "; 34 | 35 | // AutoAuth 36 | "assistant.autoAuth.tip" = "AutoAuth Logging in…"; 37 | "assistant.autoLogin.text" = "Auto Login"; 38 | 39 | 40 | // Context Menu 41 | "assistant.chat.stickyBottom" = "Sticky on Bottom"; 42 | "assistant.chat.unStickyBottom" = "Unsticky on Bottom"; 43 | "assistant.chat.multiSelect" = "Multiselect"; 44 | "assistant.chat.unMultiSelect" = "Unmultiselect"; 45 | "assistant.chat.readAll" = "Mark All As Read"; 46 | "assistant.chat.clearEmpty" = "Clear All Empty Session"; 47 | "assistant.chat.remove" = "remove"; 48 | "assistant.chat.unread" = "Unread"; 49 | 50 | // Remote Control 51 | "assistant.remoteControl.getList" = "Directive"; 52 | "assistant.remoteControl.listTip" = "remote Control Directives: \n(function-directive-Switch)\n\n"; 53 | "assistant.remoteControl.recall" = "Assistant got a directive: "; 54 | "assistant.remoteControl.voiceRecall" = "Assistant got a audio message, Convert to Text👇👇👇:"; 55 | "assistant.remoteControl.mac" = "Macbook:"; 56 | "assistant.remoteControl.app" = "APP:"; 57 | "assistant.remoteControl.neteaseMusic" = "NeteaseMusic:"; 58 | "assistant.remoteControl.assistant" = "Assistant:"; 59 | "assistant.remoteControl.open" = "On"; 60 | "assistant.remoteControl.close" = "Off"; 61 | "assistant.remoteControl.contentPlaceHodler" = "Please enter the keyword"; 62 | 63 | // Remote Control Directive 64 | "Assistant.Directive.ScreenSave" = "Screen Save"; 65 | "Assistant.Directive.LockScreen" = "Lock Screen"; 66 | "Assistant.Directive.Sleep" = "Sleep"; 67 | "Assistant.Directive.Shutdown" = "Shut Down"; 68 | "Assistant.Directive.Restart" = "Restart"; 69 | "Assistant.Directive.EmptyTrash" = "Empty Trash"; 70 | "Assistant.Directive.Mute" = "Mute"; 71 | "Assistant.Directive.KillQQ" = "Kill QQ"; 72 | "Assistant.Directive.KillWeChat" = "Kill WeChat"; 73 | "Assistant.Directive.KillChrome" = "Kill Chrome"; 74 | "Assistant.Directive.KillSafari" = "Kill Safari"; 75 | "Assistant.Directive.KillFirefox" = "Kill Firefox"; 76 | "Assistant.Directive.KillAll" = "Kill All App"; 77 | "Assistant.Directive.Toggle" = "Play/Pause"; 78 | "Assistant.Directive.Next" = "Next"; 79 | "Assistant.Directive.Previous" = "Previous"; 80 | "Assistant.Directive.VolumeUp" = "Increase Volume"; 81 | "Assistant.Directive.VolumeDown" = "Decrease Volume"; 82 | "Assistant.Directive.LikeChange" = "Like/Unlike"; 83 | "Assistant.Directive.GetList" = "Get Directive"; 84 | "Assistant.Directive.AutoReplySwitch" = "AutoReply Switch"; 85 | "Assistant.Directive.PreventRevokeSwitch" = "PreventRecall Switch"; 86 | "Assistant.Directive.AutoAuthSwitch" = "AutoAuth Switch"; 87 | "Assistant.Directive.SwitchOn" = "On"; 88 | "Assistant.Directive.SwitchOff" = "Off"; 89 | 90 | // AutoAuth Setting 91 | "assistant.autoReply.title" = "Auto Reply Setting"; 92 | "assistant.autoReply.enable" = "Enable Auto Reply"; 93 | "assistant.autoReply.enableSpecific" = "Enable Some Session Reply"; 94 | "assistant.autoReply.selectSpecific" = "View Or Edit Session"; 95 | "assistant.autoReply.enableRegEx" = "Enable RegEx"; 96 | "assistant.autoReply.enableGroup" = "Enable Group Reply"; 97 | "assistant.autoReply.enableSingle" = "Enable Single Reply"; 98 | "assistant.autoReply.delay" = "Delay Send"; 99 | "assistant.autoReply.timeUnit" = "Second"; 100 | "assistant.autoReply.contentPlaceholder" = "Reply Content(‘|’ is random reply a content)"; 101 | "assistant.autoReply.keywordPlaceholder" = "Keyword (‘*’ is All message can Reply,‘|’ is match multiple keyword)"; 102 | "assistant.autoReply.keyword" = "Keyword"; 103 | "assistant.autoReply.content" = "Reply Content"; 104 | "assistant.autoReply.list" = "Auto Reply List"; 105 | "assistant.autoReply.alert.confirm" = "OK"; 106 | "assistant.autoReply.alert.title" = "Attention"; // 107 | "assistant.autoReply.alert.content" = "Please fill in keyword and reply content"; 108 | 109 | // Version Update 110 | "assistant.update.alret.cancle" = "Cancel"; 111 | "assistant.update.alret.confirm" = "Update"; 112 | "assistant.update.alret.title" = "Found a New Version!Main Contents:👇"; 113 | "assistant.update.alret.latest" = "This is Latest Version!Main Contents:👇"; 114 | "assistant.update.alret.forbid" = "Ignore"; 115 | 116 | // Download 117 | "assistant.download.title" = "Update Assistant"; 118 | "assistant.download.cancelTitle" = "Cancelled"; 119 | "assistant.download.install" = "Ready to Install"; 120 | "assistant.download.error" = "Update Error!"; 121 | "assistant.download.update" = "Downloading update..."; 122 | "assistant.download.relaunch" = "Install and Relaunch"; 123 | "assistant.download.cancel" = "Cancel"; 124 | "assistant.download.reInstall" = "Try Again"; 125 | "assistant.download.reDownload" = "Redownload"; 126 | 127 | // Alfred 128 | "assistant.search.member" = "Member: "; 129 | "assistant.search.friend" = "[Friend]"; 130 | "assistant.search.group" = "[Group] "; 131 | "assistant.search.official" = "[Official]"; 132 | "assistant.search.chatlog" = "this is chat log👇🏻"; 133 | "assistant.search.message.unread" = "unread"; 134 | "assistant.search.yesterday" = "yesterday"; 135 | -------------------------------------------------------------------------------- /WeChatPlugin/en.lproj/about.rtfd/TXT.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg936\cocoartf1671 2 | {\fonttbl\f0\fnil\fcharset0 HelveticaNeue-Light;\f1\fnil\fcharset0 HelveticaNeue;\f2\fnil\fcharset0 HelveticaNeue-Bold; 3 | \f3\fnil\fcharset134 PingFangSC-Regular;} 4 | {\colortbl;\red255\green255\blue255;\red38\green38\blue38;\red32\green124\blue169;} 5 | {\*\expandedcolortbl;;\cssrgb\c20000\c20000\c20000;\cssrgb\c14510\c56078\c72157;} 6 | {\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1}} 7 | {\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}} 8 | \margl1440\margr1440\vieww13760\viewh11300\viewkind0 9 | \hyphauto1\hyphfactor90 10 | \deftab720 11 | \pard\pardeftab720\qc\partightenfactor0 12 | 13 | \f0\fs34 \cf2 \expnd0\expndtw0\kerning0 14 | Github: {\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS"}}{\fldrslt \cf3 WeChatPlugin-MacOS}}\ 15 | Email: {\field{\*\fldinst{HYPERLINK "mailto:tkk.ioser@gmail.com"}}{\fldrslt \cf3 tkk.ioser@gmail.com}} 16 | \f1 \ 17 | \pard\pardeftab720\sl288\slmult1\qc\partightenfactor0 18 | 19 | \fs28 \cf2 \ 20 | \pard\pardeftab720\partightenfactor0 21 | 22 | \f2\b\fs34 \cf2 Feature 23 | \fs47\fsmilli23660 \ 24 | \pard\tx220\tx720\pardeftab720\li720\fi-720\sl264\slmult1\partightenfactor0 25 | \ls1\ilvl0 26 | \f0\b0\fs30 \cf2 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 27 | Message auto reply\ 28 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 29 | Prevent message recall\ 30 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 31 | Remote control(support voice control)\ 32 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 33 | Multiple WeChat\ 34 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 35 | Auto Auth Login\ 36 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 37 | Session Sticky Bottom\ 38 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 39 | Windows Sticky Top\ 40 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 41 | Session multiple delete\ 42 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 43 | Auto Login Switch\ 44 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 45 | Quick reply to notifications\ 46 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 47 | Copy or Export Sticker\ 48 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 49 | Update plugin\ 50 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 51 | Reply or Open session by Alfred 52 | \f3\fs32 \ 53 | } -------------------------------------------------------------------------------- /WeChatPlugin/main.mm: -------------------------------------------------------------------------------- 1 | // 2 | // main.c 3 | // WeChatPlugin 4 | // 5 | // Created by TK on 2017/4/19. 6 | // Copyright © 2017年 tk. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WeChat+hook.h" 11 | #import "MMChatsTableCellView+hook.h" 12 | #import "MMStickerMessageCellView+hook.h" 13 | 14 | static void __attribute__((constructor)) initialize(void) { 15 | NSLog(@"++++++++ WeChatPlugin loaded ++++++++"); 16 | [NSObject hookWeChat]; 17 | [NSObject hookMMChatsTableCellView]; 18 | [NSObject hookMMStickerMessageCellView]; 19 | } 20 | -------------------------------------------------------------------------------- /WeChatPlugin/zh-Hans.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | WeChatPlugin 4 | 5 | Created by TK on 2018/4/14. 6 | Copyright © 2018年 tk. All rights reserved. 7 | */ 8 | 9 | 10 | // 菜单栏 11 | "assistant.menu.title" = "微信小助手"; 12 | "assistant.menu.revoke" = "开启消息防撤回"; 13 | "assistant.menu.revokeSelf" = "拦截自己撤回消息"; 14 | "assistant.menu.autoReply" = "自动回复设置"; 15 | "assistant.menu.newWeChat" = "登录新微信"; 16 | "assistant.menu.remoteControl" = "远程控制mac"; 17 | "assistant.menu.windowSticky" = "微信窗口置顶"; 18 | "assistant.menu.freeLogin" = "免认证登录"; 19 | "assistant.menu.systemBrowser" = "使用系统浏览器"; 20 | "assistant.menu.forbidCheck" = "禁止微信启动时检测更新"; 21 | "assistant.menu.other" = "小助手🌚"; 22 | "assistant.menu.enableAlfred" = "开启 Alfred 功能"; 23 | "assistant.menu.updateAssistant" = "更新小助手…"; 24 | "assistant.menu.aboutAssistant" = "关于小助手"; 25 | 26 | // 撤回相关 27 | "assistant.revokeType.emoji" = "[表情]"; 28 | "assistant.revokeType.image" = "[图片]"; 29 | "assistant.revokeType.video" = "[视频]"; 30 | "assistant.revokeType.voice" = "[语音]"; 31 | "assistant.revokeType.other" = "[非文本]"; 32 | "assistant.revoke.otherMessage.tip" = "TK拦截到一条撤回消息: "; 33 | "assistant.revoke.selfMessage.tip" = "你撤回了一条消息: "; 34 | 35 | // 免认证相关 36 | "assistant.autoAuth.tip" = "TK正在为你免认证登录~"; 37 | "assistant.autoLogin.text" = "自动登录"; 38 | 39 | 40 | // 回话选择 41 | "assistant.chat.stickyBottom" = "置底"; 42 | "assistant.chat.unStickyBottom" = "取消置底"; 43 | "assistant.chat.multiSelect" = "多选"; 44 | "assistant.chat.unMultiSelect" = "取消多选"; 45 | "assistant.chat.readAll" = "一键已读"; 46 | "assistant.chat.clearEmpty" = "清除空会话"; 47 | "assistant.chat.remove" = "移除"; 48 | "assistant.chat.unread" = "标记未读"; 49 | 50 | // 远程控制相关 51 | "assistant.remoteControl.getList" = "获取指令"; 52 | "assistant.remoteControl.listTip" = "远程控制指令:\n(功能-指令-是否开启)\n\n"; 53 | "assistant.remoteControl.recall" = "小助手收到一条指令:"; 54 | "assistant.remoteControl.voiceRecall" = "小助手收到一条语音消息,转文字后👇👇👇:"; 55 | "assistant.remoteControl.mac" = "macbook控制:"; 56 | "assistant.remoteControl.app" = "app控制:"; 57 | "assistant.remoteControl.neteaseMusic" = "网易云音乐控制:"; 58 | "assistant.remoteControl.assistant" = "小助手控制:"; 59 | "assistant.remoteControl.open" = "开启"; 60 | "assistant.remoteControl.close" = "关闭"; 61 | "assistant.remoteControl.contentPlaceHodler" = "请输入匹配的关键词"; 62 | 63 | // 远程控制指令 64 | "Assistant.Directive.ScreenSave" = "屏幕保护"; 65 | "Assistant.Directive.LockScreen" = "锁屏"; 66 | "Assistant.Directive.Sleep" = "休眠"; 67 | "Assistant.Directive.Shutdown" = "关机"; 68 | "Assistant.Directive.Restart" = "重启"; 69 | "Assistant.Directive.EmptyTrash" = "清空废纸篓"; 70 | "Assistant.Directive.Mute" = "静音"; 71 | "Assistant.Directive.KillQQ" = "退出 QQ"; 72 | "Assistant.Directive.KillWeChat" = "退出 WeChat"; 73 | "Assistant.Directive.KillChrome" = "退出 Chrome"; 74 | "Assistant.Directive.KillSafari" = "退出 Safari"; 75 | "Assistant.Directive.KillFirefox" = "退出 Firefox"; 76 | "Assistant.Directive.KillAll" = "退出所有程序"; 77 | "Assistant.Directive.Toggle" = "播放/暂停"; 78 | "Assistant.Directive.Next" = "下一首"; 79 | "Assistant.Directive.Previous" = "上一首"; 80 | "Assistant.Directive.VolumeUp" = "增大音量"; 81 | "Assistant.Directive.VolumeDown" = "VolumeDown"; 82 | "Assistant.Directive.LikeChange" = "喜欢/取消喜欢"; 83 | "Assistant.Directive.GetList" = "获取指令"; 84 | "Assistant.Directive.AutoReplySwitch" = "自动回复开关"; 85 | "Assistant.Directive.PreventRevokeSwitch" = "防撤回开关"; 86 | "Assistant.Directive.AutoAuthSwitch" = "免认证登录开关"; 87 | "Assistant.Directive.SwitchOn" = "开启"; 88 | "Assistant.Directive.SwitchOff" = "关闭"; 89 | 90 | // 自动回复 91 | "assistant.autoReply.title" = "自动回复设置"; 92 | "assistant.autoReply.enable" = "开启自动回复"; 93 | "assistant.autoReply.enableSpecific" = "开启特定回复"; 94 | "assistant.autoReply.selectSpecific" = "查看(修改)选中联系人"; 95 | "assistant.autoReply.enableRegEx" = "开启正则匹配"; 96 | "assistant.autoReply.enableGroup" = "开启群聊自动回复"; 97 | "assistant.autoReply.enableSingle" = "开启私聊自动回复"; 98 | "assistant.autoReply.delay" = "延迟发送"; 99 | "assistant.autoReply.timeUnit" = "秒"; 100 | "assistant.autoReply.contentPlaceholder" = "请输入自动回复的内容(‘|’ 为随机回复其中任一内容)"; 101 | "assistant.autoReply.keywordPlaceholder" = "请输入关键字( ‘*’ 为任何消息都回复,‘|’ 为匹配多个关键字)"; 102 | "assistant.autoReply.keyword" = "关键字"; 103 | "assistant.autoReply.content" = "回复内容"; 104 | "assistant.autoReply.list" = "自动回复列表"; 105 | "assistant.autoReply.alert.confirm" = "确定"; 106 | "assistant.autoReply.alert.title" = "您还有一条自动回复设置未完成"; 107 | "assistant.autoReply.alert.content" = "请完善未完成的自动回复设置"; 108 | 109 | // 版本更新 110 | "assistant.update.alret.cancle" = "取消"; 111 | "assistant.update.alret.confirm" = "安装更新"; 112 | "assistant.update.alret.title" = "检测到新版本!主要内容:👇"; 113 | "assistant.update.alret.latest" = "当前为最新版本!主要内容:👇"; 114 | "assistant.update.alret.forbid" = "不再提示"; 115 | 116 | // 下载 117 | "assistant.download.title" = "更新小助手"; 118 | "assistant.download.cancelTitle" = "已取消"; 119 | "assistant.download.install" = "可以开始安装了"; 120 | "assistant.download.error" = "更新错误!"; 121 | "assistant.download.update" = "正在下载更新…"; 122 | "assistant.download.relaunch" = "安装并重启应用"; 123 | "assistant.download.cancel" = "取消"; 124 | "assistant.download.reInstall" = "重试"; 125 | "assistant.download.reDownload" = "重新下载"; 126 | 127 | 128 | // alfred 搜索 129 | "assistant.search.member" = "成员:"; 130 | "assistant.search.friend" = "[好友]"; 131 | "assistant.search.group" = "[群聊]"; 132 | "assistant.search.official" = "[公众号]"; 133 | "assistant.search.chatlog" = "以下为聊天记录👇🏻"; 134 | "assistant.search.message.unread" = "未读"; 135 | "assistant.search.yesterday" = "昨天"; 136 | -------------------------------------------------------------------------------- /WeChatPlugin/zh-Hant.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | WeChatPlugin 4 | 5 | Created by TK on 2018/4/14. 6 | Copyright © 2018年 tk. All rights reserved. 7 | */ 8 | 9 | 10 | // 菜單欄 11 | "assistant.menu.title" = "微信小助手"; 12 | "assistant.menu.revoke" = "開啟消息防撤回"; 13 | "assistant.menu.revokeSelf" = "攔截自己撤回消息"; 14 | "assistant.menu.autoReply" = "自動回復設置"; 15 | "assistant.menu.newWeChat" = "登錄新微信"; 16 | "assistant.menu.remoteControl" = "遠程控制mac"; 17 | "assistant.menu.windowSticky" = "微信窗口置頂"; 18 | "assistant.menu.freeLogin" = "免認證登錄"; 19 | "assistant.menu.systemBrowser" = "使用系統瀏覽器"; 20 | "assistant.menu.forbidCheck" = "禁止微信啟動時檢測更新"; 21 | "assistant.menu.other" = "小助手🌚"; 22 | "assistant.menu.enableAlfred" = "開啟 Alfred 功能"; 23 | "assistant.menu.updateAssistant" = "更新小助手…"; 24 | "assistant.menu.aboutAssistant" = "關於小助手"; 25 | 26 | // 撤回相關 27 | "assistant.revokeType.emoji" = "[表情]"; 28 | "assistant.revokeType.image" = "[圖片]"; 29 | "assistant.revokeType.video" = "[視頻]"; 30 | "assistant.revokeType.voice" = "[語音]"; 31 | "assistant.revokeType.other" = "[非文本]"; 32 | "assistant.revoke.otherMessage.tip" = "TK攔截到一條撤回消息: "; 33 | "assistant.revoke.selfMessage.tip" = "你撤回了一條消息: "; 34 | 35 | // 免認證相關 36 | "assistant.autoAuth.tip" = "TK正在為你免認證登錄~"; 37 | "assistant.autoLogin.text" = "自動登錄"; 38 | 39 | 40 | // 回話選擇 41 | "assistant.chat.stickyBottom" = "置底"; 42 | "assistant.chat.unStickyBottom" = "取消置底"; 43 | "assistant.chat.multiSelect" = "多選"; 44 | "assistant.chat.unMultiSelect" = "取消多選"; 45 | "assistant.chat.readAll" = "一鍵已讀"; 46 | "assistant.chat.clearEmpty" = "清除空會話"; 47 | "assistant.chat.remove" = "移除"; 48 | "assistant.chat.unread" = "标记未读"; 49 | 50 | // 遠程控制相關 51 | "assistant.remoteControl.getList" = "獲取指令"; 52 | "assistant.remoteControl.listTip" = "遠程控制指令:\n(功能-指令-是否開啟)\n\n"; 53 | "assistant.remoteControl.recall" = "小助手收到一條指令:"; 54 | "assistant.remoteControl.voiceRecall" = "小助手收到一條語音消息,轉文字後👇👇👇:"; 55 | "assistant.remoteControl.mac" = "macbook控制:"; 56 | "assistant.remoteControl.app" = "app控制:"; 57 | "assistant.remoteControl.neteaseMusic" = "網易雲音樂控制:"; 58 | "assistant.remoteControl.assistant" = "小助手控制:"; 59 | "assistant.remoteControl.open" = "開啟"; 60 | "assistant.remoteControl.close" = "關閉"; 61 | "assistant.remoteControl.contentPlaceHodler" = "請輸入匹配的關鍵詞"; 62 | 63 | // 遠程控制指令 64 | "Assistant.Directive.ScreenSave" = "屏幕保護"; 65 | "Assistant.Directive.LockScreen" = "鎖屏"; 66 | "Assistant.Directive.Sleep" = "休眠"; 67 | "Assistant.Directive.Shutdown" = "關機"; 68 | "Assistant.Directive.Restart" = "重啟"; 69 | "Assistant.Directive.EmptyTrash" = "清空廢紙簍"; 70 | "Assistant.Directive.Mute" = "靜音"; 71 | "Assistant.Directive.KillQQ" = "退出 QQ"; 72 | "Assistant.Directive.KillWeChat" = "退出 WeChat"; 73 | "Assistant.Directive.KillChrome" = "退出 Chrome"; 74 | "Assistant.Directive.KillSafari" = "退出 Safari"; 75 | "Assistant.Directive.KillFirefox" = "退出 Firefox"; 76 | "Assistant.Directive.KillAll" = "退出所有程序"; 77 | "Assistant.Directive.Toggle" = "播放/暫停"; 78 | "Assistant.Directive.Next" = "下一首"; 79 | "Assistant.Directive.Previous" = "上一首"; 80 | "Assistant.Directive.VolumeUp" = "增大音量"; 81 | "Assistant.Directive.VolumeDown" = "VolumeDown"; 82 | "Assistant.Directive.LikeChange" = "喜歡/取消喜歡"; 83 | "Assistant.Directive.GetList" = "獲取指令"; 84 | "Assistant.Directive.AutoReplySwitch" = "自動回復開關"; 85 | "Assistant.Directive.PreventRevokeSwitch" = "防撤回開關"; 86 | "Assistant.Directive.AutoAuthSwitch" = "免認證登錄開關"; 87 | "Assistant.Directive.SwitchOn" = "開啟"; 88 | "Assistant.Directive.SwitchOff" = "關閉"; 89 | 90 | // 自動回復 91 | "assistant.autoReply.title" = "自動回復設置"; 92 | "assistant.autoReply.enable" = "開啟自動回復"; 93 | "assistant.autoReply.enableSpecific" = "開啟特定回復"; 94 | "assistant.autoReply.selectSpecific" = "查看(修改)選中聯系人"; 95 | "assistant.autoReply.enableRegEx" = "開啟正則匹配"; 96 | "assistant.autoReply.enableGroup" = "開啟群聊自動回復"; 97 | "assistant.autoReply.enableSingle" = "開啟私聊自動回復"; 98 | "assistant.autoReply.delay" = "延遲發送"; 99 | "assistant.autoReply.timeUnit" = "秒"; 100 | "assistant.autoReply.contentPlaceholder" = "請輸入自動回復的內容(‘|’ 為隨機回復其中任一內容)"; 101 | "assistant.autoReply.keywordPlaceholder" = "請輸入關鍵字( ‘*’ 為任何消息都回復,‘|’ 為匹配多個關鍵字)"; 102 | "assistant.autoReply.keyword" = "關鍵字"; 103 | "assistant.autoReply.content" = "回復內容"; 104 | "assistant.autoReply.list" = "自動回復列表"; 105 | "assistant.autoReply.alert.confirm" = "確定"; 106 | "assistant.autoReply.alert.title" = "您還有一條自動回復設置未完成"; 107 | "assistant.autoReply.alert.content" = "請完善未完成的自動回復設置"; 108 | 109 | // 版本更新 110 | "assistant.update.alret.cancle" = "取消"; 111 | "assistant.update.alret.confirm" = "安裝更新"; 112 | "assistant.update.alret.title" = "檢測到新版本!主要內容:👇"; 113 | "assistant.update.alret.latest" = "當前為最新版本!主要內容:👇"; 114 | "assistant.update.alret.forbid" = "不再提示"; 115 | 116 | // 下載 117 | "assistant.download.title" = "更新小助手"; 118 | "assistant.download.cancelTitle" = "已取消"; 119 | "assistant.download.install" = "可以開始安裝了"; 120 | "assistant.download.error" = "更新錯誤!"; 121 | "assistant.download.update" = "正在下載更新…"; 122 | "assistant.download.relaunch" = "安裝並重啟應用"; 123 | "assistant.download.cancel" = "取消"; 124 | "assistant.download.reInstall" = "重試"; 125 | "assistant.download.reDownload" = "重新下載"; 126 | 127 | 128 | // alfred 搜索 129 | "assistant.search.member" = "成員:"; 130 | "assistant.search.friend" = "[好友]"; 131 | "assistant.search.group" = "[群聊]"; 132 | "assistant.search.official" = "[公衆號]"; 133 | "assistant.search.chatlog" = "以下為聊天記錄👇🏻"; 134 | "assistant.search.message.unread" = "未读"; 135 | "assistant.search.yesterday" = "昨天"; 136 | -------------------------------------------------------------------------------- /WeChatPlugin/zh-Hant.lproj/about.rtfd/TXT.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg936\cocoartf1671 2 | {\fonttbl\f0\fnil\fcharset0 HelveticaNeue-Light;\f1\fnil\fcharset0 HelveticaNeue;\f2\fnil\fcharset134 PingFangSC-Semibold; 3 | \f3\fnil\fcharset0 HelveticaNeue-Bold;\f4\fnil\fcharset134 PingFangSC-Light;} 4 | {\colortbl;\red255\green255\blue255;\red38\green38\blue38;\red32\green124\blue169;} 5 | {\*\expandedcolortbl;;\cssrgb\c20000\c20000\c20000;\cssrgb\c14510\c56078\c72157;} 6 | {\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1} 7 | {\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid101\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid2}} 8 | {\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}} 9 | \margl1440\margr1440\vieww13760\viewh11300\viewkind0 10 | \hyphauto1\hyphfactor90 11 | \deftab720 12 | \pard\pardeftab720\qc\partightenfactor0 13 | 14 | \f0\fs36\fsmilli18200 \cf2 \expnd0\expndtw0\kerning0 15 | Github: {\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS"}}{\fldrslt \cf3 WeChatPlugin-MacOS}}\ 16 | Email: {\field{\*\fldinst{HYPERLINK "mailto:tkk.ioser@gmail.com"}}{\fldrslt \cf3 tkk.ioser@gmail.com}} 17 | \f1\fs32 \ 18 | \pard\pardeftab720\sl288\slmult1\qc\partightenfactor0 19 | 20 | \fs28 \cf2 \ 21 | \pard\pardeftab720\partightenfactor0 22 | 23 | \f2\b\fs36 \cf2 \'b9\'a6\'c4\'dc 24 | \f3\fs47\fsmilli23660 \cf2 \ 25 | \pard\tx220\tx720\pardeftab720\li720\fi-720\partightenfactor0 26 | \ls1\ilvl0 27 | \f0\b0\fs32 \cf2 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 28 | \f4 \expnd0\expndtw0\kerning0 29 | \'cf\'fb\'cf\'a2\'d7\'d4\'84\'d3\'bb\'d8\'8f\'cd 30 | \f0 \ 31 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 32 | \f4 \expnd0\expndtw0\kerning0 33 | \'cf\'fb\'cf\'a2\'b7\'c0\'b3\'b7\'bb\'d8 34 | \f0 \ 35 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 36 | \f4 \expnd0\expndtw0\kerning0 37 | \'df\'68\'b3\'cc\'bf\'d8\'d6\'c6 38 | \f0 ( 39 | \f4 \'d2\'d1\'d6\'a7\'b3\'d6\'d5\'5a\'d2\'f4 40 | \f0 )\ 41 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 42 | \f4 \expnd0\expndtw0\kerning0 43 | \'ce\'a2\'d0\'c5\'b6\'e0\'e9\'5f 44 | \f0 \ 45 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 46 | \f4 \expnd0\expndtw0\kerning0 47 | \'b5\'da\'b6\'fe\'b4\'ce\'b5\'c7\'e4\'9b\'c3\'e2\'d5\'4a\'d7\'43 48 | \f0 \ 49 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 50 | \f4 \expnd0\expndtw0\kerning0 51 | \'c1\'c4\'cc\'ec\'d6\'c3\'b5\'d7\'b9\'a6\'c4\'dc 52 | \f0 ( 53 | \f4 \strike \strikec2 \'ee\'90\'cb\'c6\'d6\'c3\'ed\'94 54 | \f0 \strike0\striked0 )\ 55 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 56 | \f4 \expnd0\expndtw0\kerning0 57 | \'ce\'a2\'d0\'c5\'b4\'b0\'bf\'da\'d6\'c3\'ed\'94 58 | \f0 \ 59 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 60 | \f4 \expnd0\expndtw0\kerning0 61 | \'95\'fe\'d4\'92\'b6\'e0\'df\'78\'84\'68\'b3\'fd 62 | \f0 \ 63 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 64 | \f4 \expnd0\expndtw0\kerning0 65 | \'d7\'d4\'84\'d3\'b5\'c7\'e4\'9b\'e9\'5f\'ea\'50 66 | \f0 \ 67 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 68 | \f4 \expnd0\expndtw0\kerning0 69 | \'cd\'a8\'d6\'aa\'d6\'d0\'d0\'c4\'bf\'ec\'bd\'dd\'bb\'d8\'8f\'cd 70 | \f0 \ 71 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 72 | \f4 \expnd0\expndtw0\kerning0 73 | \'c1\'c4\'cc\'ec\'b4\'b0\'bf\'da\'b1\'ed\'c7\'e9\'b0\'fc\'8f\'cd\'d6\'c6 74 | \f0 & 75 | \f4 \'b4\'e6\'83\'a6 76 | \f0 \ 77 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 } 78 | \f4 \expnd0\expndtw0\kerning0 79 | \'d0\'a1\'d6\'fa\'ca\'d6\'99\'7a\'9c\'79\'b8\'fc\'d0\'c2\'cc\'e1\'d0\'d1 80 | \f0 \ 81 | \ls1\ilvl0\kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }\expnd0\expndtw0\kerning0 82 | alfred 83 | \f4 \'bf\'ec\'bd\'dd\'b0\'6c\'cb\'cd\'cf\'fb\'cf\'a2 84 | \f0 & 85 | \f4 \'b4\'f2\'e9\'5f\'b4\'b0\'bf\'da 86 | \f0 \ 87 | \pard\tx566\pardeftab720\partightenfactor0 88 | 89 | \fs36\fsmilli18200 \cf2 \ 90 | \pard\pardeftab720\partightenfactor0 91 | 92 | \f2\b\fs36 \cf2 \'b8\'fc\'d0\'c2\'c8\'d5\'d5\'49 93 | \f3\fs47\fsmilli23660 \cf2 \ 94 | \pard\tx220\tx720\pardeftab720\li720\fi-720\sl264\slmult1\partightenfactor0 95 | \ls2\ilvl0 96 | \f0\b0\fs32 \cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.6.1"}}{\fldrslt 97 | \f4 \expnd0\expndtw0\kerning0 98 | \'d0\'c2\'d4\'f6\'d7\'d4\'84\'d3\'bb\'d8\'8f\'cd\'d1\'d3\'df\'74 99 | \f0 & 100 | \f4 \'d0\'de\'b8\'c4\'d6\'c3\'ed\'94\'b4\'b0\'bf\'da\'bf\'ec\'bd\'dd 101 | \f0 (2018-04-07)}}\cf2 \expnd0\expndtw0\kerning0 102 | \ 103 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.6"}}{\fldrslt 104 | \f4 \expnd0\expndtw0\kerning0 105 | \'d0\'c2\'d4\'f6 106 | \f0 Alfred 107 | \f4 \'bf\'ec\'bd\'dd\'b0\'6c\'cb\'cd\'cf\'fb\'cf\'a2 108 | \f0 & 109 | \f4 \'b4\'f2\'e9\'5f\'c1\'c4\'cc\'ec\'b4\'b0\'bf\'da 110 | \f0 (2018-03-18)}}\cf2 \expnd0\expndtw0\kerning0 111 | \ 112 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.5.1"}}{\fldrslt 113 | \f4 \expnd0\expndtw0\kerning0 114 | \'d0\'c2\'d4\'f6\'d5\'5a\'d2\'f4\'df\'68\'b3\'cc\'bf\'d8\'d6\'c6 115 | \f0 mac & 116 | \f4 \'83\'9e\'bb\'af\'b3\'b7\'bb\'d8\'cf\'fb\'cf\'a2\'a1\'a2\'bf\'ec\'bd\'dd\'bb\'d8\'8f\'cd 117 | \f0 (2018-03-03)}}\cf2 \expnd0\expndtw0\kerning0 118 | \ 119 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.5.0"}}{\fldrslt 120 | \f4 \expnd0\expndtw0\kerning0 121 | \'d0\'c2\'d4\'f6\'d0\'a1\'d6\'fa\'ca\'d6\'99\'7a\'9c\'79\'b8\'fc\'d0\'c2 122 | \f0 & 123 | \f4 \'b1\'ed\'c7\'e9\'b0\'fc\'8f\'cd\'d6\'c6\'b4\'e6\'83\'a6\'b5\'c8\'b5\'c8 124 | \f0 (2018-02-24)}}\cf2 \expnd0\expndtw0\kerning0 125 | \ 126 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.4.0"}}{\fldrslt 127 | \f4 \expnd0\expndtw0\kerning0 128 | \'d0\'c2\'d4\'f6\'b4\'b0\'bf\'da\'d6\'c3\'ed\'94 129 | \f0 & 130 | \f4 \'b6\'e0\'df\'78\'84\'68\'b3\'fd\'b5\'c8\'b5\'c8 131 | \f0 (2017-10-11)}}\cf2 \expnd0\expndtw0\kerning0 132 | \ 133 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.3.0"}}{\fldrslt 134 | \f4 \expnd0\expndtw0\kerning0 135 | \'d0\'c2\'d4\'f6\'d6\'c3\'b5\'d7 136 | \f0 & 137 | \f4 \'c3\'e2\'d5\'4a\'d7\'43 138 | \f0 (2017-09-17)}}\cf2 \expnd0\expndtw0\kerning0 139 | \ 140 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.2.0"}}{\fldrslt 141 | \f4 \expnd0\expndtw0\kerning0 142 | \'d0\'de\'8f\'cd\'c1\'c4\'cc\'ec\'d3\'9b\'e4\'9b\'cf\'fb\'ca\'a7\'b5\'c4 143 | \f0 bug (2017-09-11)}}\cf2 \expnd0\expndtw0\kerning0 144 | \ 145 | \ls2\ilvl0\cf3 \kerning1\expnd0\expndtw0 {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/releases/tag/v1.1.0"}}{\fldrslt 146 | \f4 \expnd0\expndtw0\kerning0 147 | \'d6\'d8\'98\'8b\'d7\'d4\'84\'d3\'bb\'d8\'8f\'cd\'a3\'ac\'8c\'8d\'ac\'46\'b6\'e0\'bb\'d8\'8f\'cd 148 | \f0 (2017-08-23)}}\cf2 \expnd0\expndtw0\kerning0 149 | \ 150 | \pard\pardeftab720\sl264\slmult1\partightenfactor0 151 | 152 | \f2\b \cf2 \'d4\'94\'bc\'9a\'83\'c8\'c8\'dd\'d5\'88\'b2\'e9\'bf\'b4{\field{\*\fldinst{HYPERLINK "https://github.com/TKkk-iOSer/WeChatPlugin-MacOS/blob/master/CHANGELOG.md"}}{\fldrslt 153 | \f0\b0 \cf3 CHANGELOG}} 154 | \f0\b0\fs36\fsmilli18200 \cf2 \ 155 | } --------------------------------------------------------------------------------