mirror of
https://github.com/Sunnyyoung/WeChatTweak-macOS.git
synced 2025-07-09 01:08:46 +08:00
commit
c69db6d911
5
CONTRIBUTING.md
Normal file
5
CONTRIBUTING.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Contributing
|
||||
|
||||
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
|
||||
|
||||
[](https://github.com/Sunnyyoung/WeChatTweak-macOS/graphs/contributors)
|
214
LICENSE
214
LICENSE
|
@ -1,21 +1,201 @@
|
|||
MIT License
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
Copyright (c) 2016 Sunnyyoung
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
1. Definitions.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
16
Podfile.lock
16
Podfile.lock
|
@ -1,7 +1,7 @@
|
|||
PODS:
|
||||
- GCDWebServer (3.4.1):
|
||||
- GCDWebServer/Core (= 3.4.1)
|
||||
- GCDWebServer/Core (3.4.1)
|
||||
- GCDWebServer (3.4.2):
|
||||
- GCDWebServer/Core (= 3.4.2)
|
||||
- GCDWebServer/Core (3.4.2)
|
||||
- JRSwizzle (1.0)
|
||||
- YYModel (1.0.4)
|
||||
|
||||
|
@ -10,11 +10,17 @@ DEPENDENCIES:
|
|||
- JRSwizzle
|
||||
- YYModel
|
||||
|
||||
SPEC REPOS:
|
||||
https://github.com/cocoapods/specs.git:
|
||||
- GCDWebServer
|
||||
- JRSwizzle
|
||||
- YYModel
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
GCDWebServer: 1db60034fe0e78a4a8524bd6c7cd97cd3c589870
|
||||
GCDWebServer: 8d67ee9f634b4bb91eb4b8aee440318a5fc6debd
|
||||
JRSwizzle: dd5ead5d913a0f29e7f558200165849f006bb1e3
|
||||
YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30
|
||||
|
||||
PODFILE CHECKSUM: af44d62b300e2c55cb63386ec4be3227b93c7761
|
||||
|
||||
COCOAPODS: 1.3.1
|
||||
COCOAPODS: 1.5.3
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
# WeChatTweak-macOS
|
||||
|
||||
[](LICENSE)
|
||||
[](LICENSE)
|
||||
[](README.md)
|
||||
[](README-Chinese.md)
|
||||
[](https://t.me/joinchat/B0vW8kPU5OrwdC1qRbaqRA)
|
||||
[](#backers)
|
||||
[](#sponsors)
|
||||
|
||||
微信 macOS 客户端 Tweak 动态库。
|
||||
|
||||
|
@ -11,24 +13,29 @@
|
|||
|
||||
### 整体预览
|
||||
|
||||

|
||||

|
||||
|
||||
### Alfred workflow
|
||||
|
||||

|
||||

|
||||
|
||||
### LaunchBar action
|
||||
|
||||

|
||||
|
||||
## 功能
|
||||
|
||||
- 阻止消息撤回
|
||||
- 消息列表通知
|
||||
- 系统通知
|
||||
- 正常撤回自己发出的消息
|
||||
- 消息列表通知
|
||||
- 系统通知
|
||||
- 正常撤回自己发出的消息
|
||||
- 客户端无限多开
|
||||
- 右键 dock icon 登录新的微信账号
|
||||
- 命令行执行:`open -n /Applications/WeChat.app`
|
||||
- 右键 dock icon 登录新的微信账号
|
||||
- 命令行执行:`open -n /Applications/WeChat.app`
|
||||
- 重新打开应用无需手机认证
|
||||
- UI界面设置面板
|
||||
- 支持 Alfred workflow
|
||||
- 支持 Launchbar action
|
||||
|
||||
## 使用
|
||||
|
||||
|
@ -51,6 +58,33 @@
|
|||
- [微信 macOS 客户端拦截撤回功能实践](https://blog.sunnyyoung.net/wei-xin-macos-ke-hu-duan-lan-jie-che-hui-gong-neng-shi-jian/)
|
||||
- [让微信 macOS 客户端支持 Alfred](https://blog.sunnyyoung.net/rang-wei-xin-macos-ke-hu-duan-zhi-chi-alfred/)
|
||||
|
||||
## 贡献者
|
||||
|
||||
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
|
||||
|
||||
[](/graphs/contributors)
|
||||
|
||||
## 支持者
|
||||
|
||||
Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/WeChatTweak-macOS#backer)]
|
||||
|
||||
[](https://opencollective.com/WeChatTweak-macOS#backers)
|
||||
|
||||
## 赞助者
|
||||
|
||||
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/WeChatTweak-macOS#sponsor)]
|
||||
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/0/website)
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/1/website)
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/2/website)
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/3/website)
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/4/website)
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/5/website)
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/6/website)
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/7/website)
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/8/website)
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/9/website)
|
||||
|
||||
## License
|
||||
|
||||
The [MIT License](LICENSE).
|
||||
The [Apache License 2.0](LICENSE).
|
||||
|
|
52
README.md
52
README.md
|
@ -1,9 +1,11 @@
|
|||
# WeChatTweak-macOS
|
||||
|
||||
[](LICENSE)
|
||||
[](LICENSE)
|
||||
[](README.md)
|
||||
[](README-Chinese.md)
|
||||
[](https://t.me/joinchat/B0vW8kPU5OrwdC1qRbaqRA)
|
||||
[](#backers)
|
||||
[](#sponsors)
|
||||
|
||||
A dynamic library tweak for WeChat macOS.
|
||||
|
||||
|
@ -11,24 +13,29 @@ A dynamic library tweak for WeChat macOS.
|
|||
|
||||
### Overview
|
||||
|
||||

|
||||

|
||||
|
||||
### Alfred workflow
|
||||
|
||||

|
||||

|
||||
|
||||
### LaunchBar action
|
||||
|
||||

|
||||
|
||||
## Feature
|
||||
|
||||
- Prevent message revoked
|
||||
- Message list notification
|
||||
- System notification
|
||||
- Revoke message you sent
|
||||
- Message list notification
|
||||
- System notification
|
||||
- Revoke message you sent
|
||||
- Multiple WeChat Instance
|
||||
- Right click on the dock icon to login another WeChat account
|
||||
- Run command: `open -n /Applications/WeChat.app`
|
||||
- Right click on the dock icon to login another WeChat account
|
||||
- Run command: `open -n /Applications/WeChat.app`
|
||||
- Auto login without authentication
|
||||
- UI Interface settings panel
|
||||
- Alfred workflow support
|
||||
- Launchbar action support
|
||||
|
||||
## Quick Start
|
||||
|
||||
|
@ -51,6 +58,33 @@ For more informations, please go to the [Wiki](https://github.com/Sunnyyoung/WeC
|
|||
- [微信 macOS 客户端拦截撤回功能实践](https://blog.sunnyyoung.net/wei-xin-macos-ke-hu-duan-lan-jie-che-hui-gong-neng-shi-jian/)
|
||||
- [让微信 macOS 客户端支持 Alfred](https://blog.sunnyyoung.net/rang-wei-xin-macos-ke-hu-duan-zhi-chi-alfred/)
|
||||
|
||||
## Contributors
|
||||
|
||||
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
|
||||
|
||||
[](https://github.com/Sunnyyoung/WeChatTweak-macOS/graphs/contributors)
|
||||
|
||||
## Backers
|
||||
|
||||
Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/WeChatTweak-macOS#backer)]
|
||||
|
||||
[](https://opencollective.com/WeChatTweak-macOS#backers)
|
||||
|
||||
## Sponsors
|
||||
|
||||
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/WeChatTweak-macOS#sponsor)]
|
||||
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/0/website)
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/1/website)
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/2/website)
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/3/website)
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/4/website)
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/5/website)
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/6/website)
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/7/website)
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/8/website)
|
||||
[](https://opencollective.com/WeChatTweak-macOS/sponsor/9/website)
|
||||
|
||||
## License
|
||||
|
||||
The [MIT License](LICENSE).
|
||||
The [Apache License 2.0](LICENSE).
|
||||
|
|
BIN
Screenshot/0x03.png
Normal file
BIN
Screenshot/0x03.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
Binary file not shown.
1
WeChatTweak.framework/Headers
Symbolic link
1
WeChatTweak.framework/Headers
Symbolic link
|
@ -0,0 +1 @@
|
|||
Versions/Current/Headers
|
1
WeChatTweak.framework/Modules
Symbolic link
1
WeChatTweak.framework/Modules
Symbolic link
|
@ -0,0 +1 @@
|
|||
Versions/Current/Modules
|
15
WeChatTweak.framework/Versions/A/Headers/WeChatTweak.h
Normal file
15
WeChatTweak.framework/Versions/A/Headers/WeChatTweak.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// WeChatTweak.h
|
||||
// WeChatTweak
|
||||
//
|
||||
// Created by Sunnyyoung on 2017/8/11.
|
||||
// Copyright © 2017年 Sunnyyoung. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <objc/runtime.h>
|
||||
#import <objc/message.h>
|
||||
#import <JRSwizzle/JRSwizzle.h>
|
||||
|
||||
FOUNDATION_EXPORT double WeChatTweakVersionNumber;
|
||||
FOUNDATION_EXPORT const unsigned char WeChatTweakVersionString[];
|
|
@ -0,0 +1,6 @@
|
|||
framework module WeChatTweak {
|
||||
umbrella header "WeChatTweak.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
BIN
WeChatTweak.framework/Versions/A/Resources/Base.lproj/TweakPreferecesController.nib
generated
Normal file
BIN
WeChatTweak.framework/Versions/A/Resources/Base.lproj/TweakPreferecesController.nib
generated
Normal file
Binary file not shown.
|
@ -3,7 +3,7 @@
|
|||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildMachineOSBuild</key>
|
||||
<string>16G29</string>
|
||||
<string>18A391</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
|
@ -27,17 +27,17 @@
|
|||
<key>DTCompiler</key>
|
||||
<string>com.apple.compilers.llvm.clang.1_0</string>
|
||||
<key>DTPlatformBuild</key>
|
||||
<string>8E3004b</string>
|
||||
<string>10A255</string>
|
||||
<key>DTPlatformVersion</key>
|
||||
<string>GM</string>
|
||||
<key>DTSDKBuild</key>
|
||||
<string>16E185</string>
|
||||
<string>18A384</string>
|
||||
<key>DTSDKName</key>
|
||||
<string>macosx10.12</string>
|
||||
<string>macosx10.14</string>
|
||||
<key>DTXcode</key>
|
||||
<string>0833</string>
|
||||
<string>1000</string>
|
||||
<key>DTXcodeBuild</key>
|
||||
<string>8E3004b</string>
|
||||
<string>10A255</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2017年 Sunnyyoung. All rights reserved.</string>
|
||||
</dict>
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,33 @@
|
|||
|
||||
/* Class = "NSMenuItem"; title = "Enabled"; ObjectID = "10G-t9-s4T"; */
|
||||
"10G-t9-s4T.title" = "Enabled";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Need to restart"; ObjectID = "2vl-mc-m3L"; */
|
||||
"2vl-mc-m3L.title" = "Need to restart";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Enabled"; ObjectID = "KQg-jN-y9a"; */
|
||||
"KQg-jN-y9a.title" = "Enabled";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Disabled"; ObjectID = "MEN-Kg-wfj"; */
|
||||
"MEN-Kg-wfj.title" = "Disabled";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Message recall notification:"; ObjectID = "UKv-CM-nGt"; */
|
||||
"UKv-CM-nGt.title" = "Message recall notification:";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Auto login:"; ObjectID = "UiV-zj-l6I"; */
|
||||
"UiV-zj-l6I.title" = "Auto login:";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Disabled"; ObjectID = "Uk9-Oc-Jtv"; */
|
||||
"Uk9-Oc-Jtv.title" = "Disabled";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Disabled"; ObjectID = "Vcv-eD-OM9"; */
|
||||
"Vcv-eD-OM9.title" = "Disabled";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "All"; ObjectID = "da4-aJ-lEy"; */
|
||||
"da4-aJ-lEy.title" = "All";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Inherited"; ObjectID = "gec-CY-E1x"; */
|
||||
"gec-CY-E1x.title" = "Inherited";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Alfred JSON compressing:"; ObjectID = "jHw-2a-B2t"; */
|
||||
"jHw-2a-B2t.title" = "Alfred JSON compressing:";
|
Binary file not shown.
|
@ -0,0 +1,33 @@
|
|||
|
||||
/* Class = "NSMenuItem"; title = "Enabled"; ObjectID = "10G-t9-s4T"; */
|
||||
"10G-t9-s4T.title" = "开启";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Need to restart"; ObjectID = "2vl-mc-m3L"; */
|
||||
"2vl-mc-m3L.title" = "需重启客户端";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Enabled"; ObjectID = "KQg-jN-y9a"; */
|
||||
"KQg-jN-y9a.title" = "开启";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Disabled"; ObjectID = "MEN-Kg-wfj"; */
|
||||
"MEN-Kg-wfj.title" = "关闭";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Message recall notification:"; ObjectID = "UKv-CM-nGt"; */
|
||||
"UKv-CM-nGt.title" = "消息撤回通知:";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Auto login:"; ObjectID = "UiV-zj-l6I"; */
|
||||
"UiV-zj-l6I.title" = "免认证登录:";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Disabled"; ObjectID = "Uk9-Oc-Jtv"; */
|
||||
"Uk9-Oc-Jtv.title" = "关闭";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Disabled"; ObjectID = "Vcv-eD-OM9"; */
|
||||
"Vcv-eD-OM9.title" = "关闭";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "All"; ObjectID = "da4-aJ-lEy"; */
|
||||
"da4-aJ-lEy.title" = "全部接收";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Inherited"; ObjectID = "gec-CY-E1x"; */
|
||||
"gec-CY-E1x.title" = "跟随聊天设置";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Alfred JSON compressing:"; ObjectID = "jHw-2a-B2t"; */
|
||||
"jHw-2a-B2t.title" = "Alfred JSON 压缩:";
|
Binary file not shown.
|
@ -0,0 +1,33 @@
|
|||
|
||||
/* Class = "NSMenuItem"; title = "Enabled"; ObjectID = "10G-t9-s4T"; */
|
||||
"10G-t9-s4T.title" = "開啟";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Need to restart"; ObjectID = "2vl-mc-m3L"; */
|
||||
"2vl-mc-m3L.title" = "需重啟客戶端";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Enabled"; ObjectID = "KQg-jN-y9a"; */
|
||||
"KQg-jN-y9a.title" = "開啟";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Disabled"; ObjectID = "MEN-Kg-wfj"; */
|
||||
"MEN-Kg-wfj.title" = "關閉";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Message recall notification:"; ObjectID = "UKv-CM-nGt"; */
|
||||
"UKv-CM-nGt.title" = "消息撤回通知:";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Auto login:"; ObjectID = "UiV-zj-l6I"; */
|
||||
"UiV-zj-l6I.title" = "免認證登錄:";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Disabled"; ObjectID = "Uk9-Oc-Jtv"; */
|
||||
"Uk9-Oc-Jtv.title" = "關閉";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Disabled"; ObjectID = "Vcv-eD-OM9"; */
|
||||
"Vcv-eD-OM9.title" = "關閉";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "All"; ObjectID = "da4-aJ-lEy"; */
|
||||
"da4-aJ-lEy.title" = "全部接收";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Inherited"; ObjectID = "gec-CY-E1x"; */
|
||||
"gec-CY-E1x.title" = "跟隨聊天設置";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Alfred JSON compressing:"; ObjectID = "jHw-2a-B2t"; */
|
||||
"jHw-2a-B2t.title" = "Alfred JSON 壓縮:";
|
Binary file not shown.
53
WeChatTweak.lbaction/Contents/Info.plist
Normal file
53
WeChatTweak.lbaction/Contents/Info.plist
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>icon.png</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.viko16.LaunchBar.action.WeChatTweak</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>WeChatTweak</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>LBAbbreviation</key>
|
||||
<string>wc</string>
|
||||
<key>LBDescription</key>
|
||||
<dict>
|
||||
<key>LBAuthor</key>
|
||||
<string>viko16</string>
|
||||
<key>LBEmail</key>
|
||||
<string></string>
|
||||
<key>LBSummary</key>
|
||||
<string>A LaunchBar action for WeChatTweak.</string>
|
||||
<key>LBTwitter</key>
|
||||
<string></string>
|
||||
<key>LBWebsiteURL</key>
|
||||
<string>https://github.com/viko16</string>
|
||||
</dict>
|
||||
<key>LBScripts</key>
|
||||
<dict>
|
||||
<key>LBDefaultScript</key>
|
||||
<dict>
|
||||
<key>LBAcceptedArgumentTypes</key>
|
||||
<array>
|
||||
<string>string</string>
|
||||
</array>
|
||||
<key>LBKeepWindowActive</key>
|
||||
<true/>
|
||||
<key>LBLiveFeedbackEnabled</key>
|
||||
<true/>
|
||||
<key>LBRequiresArgument</key>
|
||||
<true/>
|
||||
<key>LBResultType</key>
|
||||
<string>unknown</string>
|
||||
<key>LBReturnsResult</key>
|
||||
<true/>
|
||||
<key>LBScriptName</key>
|
||||
<string>default.js</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>LBTextInputTitle</key>
|
||||
<string>Search your friend...</string>
|
||||
</dict>
|
||||
</plist>
|
BIN
WeChatTweak.lbaction/Contents/Resources/icon.png
Normal file
BIN
WeChatTweak.lbaction/Contents/Resources/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
32
WeChatTweak.lbaction/Contents/Scripts/default.js
Normal file
32
WeChatTweak.lbaction/Contents/Scripts/default.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
// LaunchBar Action Script
|
||||
|
||||
function run(string) {
|
||||
if (!string) return [];
|
||||
|
||||
var url = 'http://localhost:48065/wechat/search?keyword=';
|
||||
var result = HTTP.getJSON(url + encodeURIComponent(string.trim()));
|
||||
|
||||
if (result == undefined) {
|
||||
LaunchBar.alert('HTTP.getJSON() returned undefined');
|
||||
return [];
|
||||
}
|
||||
|
||||
if (result.error != undefined) {
|
||||
LaunchBar.log('Error in HTTP request: ' + result.error);
|
||||
return [];
|
||||
}
|
||||
|
||||
return result.data.map(function (i) {
|
||||
return {
|
||||
title: i.m_nsRemark || i.m_nsNickName,
|
||||
subtitle: i.m_nsNickName,
|
||||
icon: i.wt_avatarPath || 'icon.png',
|
||||
action: "open",
|
||||
actionArgument: i.m_nsUsrName
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function open(id) {
|
||||
HTTP.get('http://localhost:48065/wechat/start?session=' + id);
|
||||
}
|
|
@ -9,50 +9,50 @@
|
|||
/* Begin PBXBuildFile section */
|
||||
7D14E5A41F6447DB00D75132 /* AlfredManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 7D14E5A21F6447DB00D75132 /* AlfredManager.h */; };
|
||||
7D14E5A51F6447DB00D75132 /* AlfredManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D14E5A31F6447DB00D75132 /* AlfredManager.m */; };
|
||||
7D54A05C20E74D9400CB5306 /* TweakPreferecesController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7D54A05E20E74D9400CB5306 /* TweakPreferecesController.xib */; };
|
||||
7D54A06A20E74FE500CB5306 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D54A06C20E74FE500CB5306 /* Localizable.strings */; };
|
||||
7D9049F51F82A41A004E6370 /* fishhook.c in Sources */ = {isa = PBXBuildFile; fileRef = 7D9049F31F82A415004E6370 /* fishhook.c */; };
|
||||
7D9049F61F82A41A004E6370 /* fishhook.h in Headers */ = {isa = PBXBuildFile; fileRef = 7D9049F41F82A415004E6370 /* fishhook.h */; };
|
||||
7D9049F91F82B6FB004E6370 /* NSString+WeChatTweak.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D9049F81F82B6FB004E6370 /* NSString+WeChatTweak.m */; };
|
||||
7D9049FA1F82B708004E6370 /* NSString+WeChatTweak.h in Headers */ = {isa = PBXBuildFile; fileRef = 7D9049F71F82B6FB004E6370 /* NSString+WeChatTweak.h */; };
|
||||
7DB8AFBE206211D900E683AE /* WTConfigManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 7DB8AFBC206211D900E683AE /* WTConfigManager.h */; };
|
||||
7DB8AFBF206211D900E683AE /* WTConfigManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DB8AFBD206211D900E683AE /* WTConfigManager.m */; };
|
||||
7DF8422C1F40583F00D42D79 /* WeChatTweak.h in Headers */ = {isa = PBXBuildFile; fileRef = 7DF8422A1F40583F00D42D79 /* WeChatTweak.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
7DF842341F4058AB00D42D79 /* WeChatTweak.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DF842331F4058AB00D42D79 /* WeChatTweak.m */; };
|
||||
7DF842521F4058C600D42D79 /* TweakPreferecesController.h in Headers */ = {isa = PBXBuildFile; fileRef = 7DF8424F1F4058C600D42D79 /* TweakPreferecesController.h */; };
|
||||
7DF842531F4058C600D42D79 /* TweakPreferecesController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DF842501F4058C600D42D79 /* TweakPreferecesController.m */; };
|
||||
7DF842541F4058C600D42D79 /* TweakPreferecesController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7DF842511F4058C600D42D79 /* TweakPreferecesController.xib */; };
|
||||
7DF8425B1F4058DD00D42D79 /* NSBundle+WeChatTweak.h in Headers */ = {isa = PBXBuildFile; fileRef = 7DF842571F4058DD00D42D79 /* NSBundle+WeChatTweak.h */; };
|
||||
7DF8425C1F4058DD00D42D79 /* NSBundle+WeChatTweak.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DF842581F4058DD00D42D79 /* NSBundle+WeChatTweak.m */; };
|
||||
7DF8425D1F4058DD00D42D79 /* NSString+WeChatTweak.h in Headers */ = {isa = PBXBuildFile; fileRef = 7DF842591F4058DD00D42D79 /* NSString+WeChatTweak.h */; };
|
||||
7DF8425E1F4058DD00D42D79 /* NSString+WeChatTweak.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DF8425A1F4058DD00D42D79 /* NSString+WeChatTweak.m */; };
|
||||
7DF842601F40590500D42D79 /* WeChatTweakHeaders.h in Headers */ = {isa = PBXBuildFile; fileRef = 7DF8425F1F40590500D42D79 /* WeChatTweakHeaders.h */; };
|
||||
7DF842621F40592800D42D79 /* WeChatTweak.framework in Export Framework */ = {isa = PBXBuildFile; fileRef = 7DF842271F40583F00D42D79 /* WeChatTweak.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
7DF842651F40594400D42D79 /* Prefs-Tweak.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 7DF842641F40594400D42D79 /* Prefs-Tweak.tiff */; };
|
||||
D84599A16A2504BCF95DB436 /* libPods-WeChatTweak.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 153504EC5C9196C0D85213CF /* libPods-WeChatTweak.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
7DF842611F40592100D42D79 /* Export Framework */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "${SRCROOT}";
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
7DF842621F40592800D42D79 /* WeChatTweak.framework in Export Framework */,
|
||||
);
|
||||
name = "Export Framework";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
153504EC5C9196C0D85213CF /* libPods-WeChatTweak.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-WeChatTweak.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7D14E5A21F6447DB00D75132 /* AlfredManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlfredManager.h; sourceTree = "<group>"; };
|
||||
7D14E5A31F6447DB00D75132 /* AlfredManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AlfredManager.m; sourceTree = "<group>"; };
|
||||
7D54A05F20E74E4600CB5306 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/TweakPreferecesController.xib; sourceTree = "<group>"; };
|
||||
7D54A06320E74E5A00CB5306 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/TweakPreferecesController.strings; sourceTree = "<group>"; };
|
||||
7D54A06520E74E8200CB5306 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/TweakPreferecesController.strings"; sourceTree = "<group>"; };
|
||||
7D54A06720E74E8E00CB5306 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/TweakPreferecesController.strings"; sourceTree = "<group>"; };
|
||||
7D54A07020E74FFD00CB5306 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
7D54A07120E7535F00CB5306 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||
7D54A07220E7536300CB5306 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||
7D9049F31F82A415004E6370 /* fishhook.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = fishhook.c; sourceTree = "<group>"; };
|
||||
7D9049F41F82A415004E6370 /* fishhook.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = fishhook.h; sourceTree = "<group>"; };
|
||||
7D9049F71F82B6FB004E6370 /* NSString+WeChatTweak.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSString+WeChatTweak.h"; sourceTree = "<group>"; };
|
||||
7D9049F81F82B6FB004E6370 /* NSString+WeChatTweak.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSString+WeChatTweak.m"; sourceTree = "<group>"; };
|
||||
7DB8AFBC206211D900E683AE /* WTConfigManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WTConfigManager.h; sourceTree = "<group>"; };
|
||||
7DB8AFBD206211D900E683AE /* WTConfigManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WTConfigManager.m; sourceTree = "<group>"; };
|
||||
7DF842271F40583F00D42D79 /* WeChatTweak.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = WeChatTweak.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7DF8422A1F40583F00D42D79 /* WeChatTweak.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WeChatTweak.h; sourceTree = "<group>"; };
|
||||
7DF8422B1F40583F00D42D79 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
7DF842331F4058AB00D42D79 /* WeChatTweak.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WeChatTweak.m; sourceTree = "<group>"; };
|
||||
7DF8424F1F4058C600D42D79 /* TweakPreferecesController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TweakPreferecesController.h; sourceTree = "<group>"; };
|
||||
7DF842501F4058C600D42D79 /* TweakPreferecesController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TweakPreferecesController.m; sourceTree = "<group>"; };
|
||||
7DF842511F4058C600D42D79 /* TweakPreferecesController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TweakPreferecesController.xib; sourceTree = "<group>"; };
|
||||
7DF842571F4058DD00D42D79 /* NSBundle+WeChatTweak.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSBundle+WeChatTweak.h"; sourceTree = "<group>"; };
|
||||
7DF842581F4058DD00D42D79 /* NSBundle+WeChatTweak.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSBundle+WeChatTweak.m"; sourceTree = "<group>"; };
|
||||
7DF842591F4058DD00D42D79 /* NSString+WeChatTweak.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+WeChatTweak.h"; sourceTree = "<group>"; };
|
||||
7DF8425A1F4058DD00D42D79 /* NSString+WeChatTweak.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+WeChatTweak.m"; sourceTree = "<group>"; };
|
||||
7DF8425F1F40590500D42D79 /* WeChatTweakHeaders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeChatTweakHeaders.h; sourceTree = "<group>"; };
|
||||
7DF842641F40594400D42D79 /* Prefs-Tweak.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = "Prefs-Tweak.tiff"; sourceTree = "<group>"; };
|
||||
A82E6F61C63DBD47219BB308 /* Pods-WeChatTweak.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WeChatTweak.debug.xcconfig"; path = "Pods/Target Support Files/Pods-WeChatTweak/Pods-WeChatTweak.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
|
@ -79,13 +79,55 @@
|
|||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7D14E5A11F6447B900D75132 /* Manager */ = {
|
||||
7D5AAF3320DF4B7B00860EEE /* Manager */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7D14E5A21F6447DB00D75132 /* AlfredManager.h */,
|
||||
7D14E5A31F6447DB00D75132 /* AlfredManager.m */,
|
||||
7DB8AFBC206211D900E683AE /* WTConfigManager.h */,
|
||||
7DB8AFBD206211D900E683AE /* WTConfigManager.m */,
|
||||
);
|
||||
name = Manager;
|
||||
path = Manager;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7D5AAF3520DF4B9700860EEE /* Controller */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7DF8424F1F4058C600D42D79 /* TweakPreferecesController.h */,
|
||||
7DF842501F4058C600D42D79 /* TweakPreferecesController.m */,
|
||||
7D54A05E20E74D9400CB5306 /* TweakPreferecesController.xib */,
|
||||
);
|
||||
path = Controller;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7D5AAF3620DF4BA400860EEE /* Category */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7DF842571F4058DD00D42D79 /* NSBundle+WeChatTweak.h */,
|
||||
7DF842581F4058DD00D42D79 /* NSBundle+WeChatTweak.m */,
|
||||
7D9049F71F82B6FB004E6370 /* NSString+WeChatTweak.h */,
|
||||
7D9049F81F82B6FB004E6370 /* NSString+WeChatTweak.m */,
|
||||
);
|
||||
path = Category;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7D5AAF3720DF4BB300860EEE /* Vendor */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7D9049F41F82A415004E6370 /* fishhook.h */,
|
||||
7D9049F31F82A415004E6370 /* fishhook.c */,
|
||||
);
|
||||
path = Vendor;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7D5AAF3820DF4BC400860EEE /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7DF8425F1F40590500D42D79 /* WeChatTweakHeaders.h */,
|
||||
7DF8422B1F40583F00D42D79 /* Info.plist */,
|
||||
7D54A06C20E74FE500CB5306 /* Localizable.strings */,
|
||||
);
|
||||
path = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7DF8421D1F40583F00D42D79 = {
|
||||
|
@ -111,45 +153,16 @@
|
|||
children = (
|
||||
7DF8422A1F40583F00D42D79 /* WeChatTweak.h */,
|
||||
7DF842331F4058AB00D42D79 /* WeChatTweak.m */,
|
||||
7D14E5A11F6447B900D75132 /* Manager */,
|
||||
7DF842551F4058C900D42D79 /* Controller */,
|
||||
7DF842561F4058D300D42D79 /* Category */,
|
||||
7D5AAF3720DF4BB300860EEE /* Vendor */,
|
||||
7D5AAF3620DF4BA400860EEE /* Category */,
|
||||
7D5AAF3520DF4B9700860EEE /* Controller */,
|
||||
7D5AAF3320DF4B7B00860EEE /* Manager */,
|
||||
7DF842631F40594400D42D79 /* Resources */,
|
||||
7DF842321F40584700D42D79 /* Supporting Files */,
|
||||
7D5AAF3820DF4BC400860EEE /* Supporting Files */,
|
||||
);
|
||||
path = WeChatTweak;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7DF842321F40584700D42D79 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7DF8425F1F40590500D42D79 /* WeChatTweakHeaders.h */,
|
||||
7DF8422B1F40583F00D42D79 /* Info.plist */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7DF842551F4058C900D42D79 /* Controller */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7DF8424F1F4058C600D42D79 /* TweakPreferecesController.h */,
|
||||
7DF842501F4058C600D42D79 /* TweakPreferecesController.m */,
|
||||
7DF842511F4058C600D42D79 /* TweakPreferecesController.xib */,
|
||||
);
|
||||
name = Controller;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7DF842561F4058D300D42D79 /* Category */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7DF842571F4058DD00D42D79 /* NSBundle+WeChatTweak.h */,
|
||||
7DF842581F4058DD00D42D79 /* NSBundle+WeChatTweak.m */,
|
||||
7DF842591F4058DD00D42D79 /* NSString+WeChatTweak.h */,
|
||||
7DF8425A1F4058DD00D42D79 /* NSString+WeChatTweak.m */,
|
||||
);
|
||||
name = Category;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7DF842631F40594400D42D79 /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -174,12 +187,14 @@
|
|||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7D9049FA1F82B708004E6370 /* NSString+WeChatTweak.h in Headers */,
|
||||
7DF8422C1F40583F00D42D79 /* WeChatTweak.h in Headers */,
|
||||
7DF8425B1F4058DD00D42D79 /* NSBundle+WeChatTweak.h in Headers */,
|
||||
7DB8AFBE206211D900E683AE /* WTConfigManager.h in Headers */,
|
||||
7D9049F61F82A41A004E6370 /* fishhook.h in Headers */,
|
||||
7D14E5A41F6447DB00D75132 /* AlfredManager.h in Headers */,
|
||||
7DF842601F40590500D42D79 /* WeChatTweakHeaders.h in Headers */,
|
||||
7DF842521F4058C600D42D79 /* TweakPreferecesController.h in Headers */,
|
||||
7DF8425D1F4058DD00D42D79 /* NSString+WeChatTweak.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -195,8 +210,7 @@
|
|||
7DF842231F40583F00D42D79 /* Frameworks */,
|
||||
7DF842241F40583F00D42D79 /* Headers */,
|
||||
7DF842251F40583F00D42D79 /* Resources */,
|
||||
B75BB08B5F9B62E8FF4DEE05 /* [CP] Copy Pods Resources */,
|
||||
7DF842611F40592100D42D79 /* Export Framework */,
|
||||
7DE5D07F218319DF00ABCE56 /* Export Framework */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
@ -213,7 +227,7 @@
|
|||
7DF8421E1F40583F00D42D79 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0830;
|
||||
LastUpgradeCheck = 0940;
|
||||
ORGANIZATIONNAME = Sunnyyoung;
|
||||
TargetAttributes = {
|
||||
7DF842261F40583F00D42D79 = {
|
||||
|
@ -228,6 +242,9 @@
|
|||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
"zh-Hans",
|
||||
"zh-Hant",
|
||||
);
|
||||
mainGroup = 7DF8421D1F40583F00D42D79;
|
||||
productRefGroup = 7DF842281F40583F00D42D79 /* Products */;
|
||||
|
@ -245,27 +262,31 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7DF842651F40594400D42D79 /* Prefs-Tweak.tiff in Resources */,
|
||||
7DF842541F4058C600D42D79 /* TweakPreferecesController.xib in Resources */,
|
||||
7D54A06A20E74FE500CB5306 /* Localizable.strings in Resources */,
|
||||
7D54A05C20E74D9400CB5306 /* TweakPreferecesController.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
B75BB08B5F9B62E8FF4DEE05 /* [CP] Copy Pods Resources */ = {
|
||||
7DE5D07F218319DF00ABCE56 /* Export Framework */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
name = "Export Framework";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-WeChatTweak/Pods-WeChatTweak-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
shellScript = "FRAMEWORK=\"${TARGET_NAME}.framework\"\nrm -r \"${SRCROOT}/${FRAMEWORK}\"\ncp -R \"${BUILT_PRODUCTS_DIR}/${FRAMEWORK}\" \"${SRCROOT}\"\n";
|
||||
};
|
||||
CB198514792C1F69F3B65026 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
|
@ -293,35 +314,70 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7D14E5A51F6447DB00D75132 /* AlfredManager.m in Sources */,
|
||||
7DF8425E1F4058DD00D42D79 /* NSString+WeChatTweak.m in Sources */,
|
||||
7DF842531F4058C600D42D79 /* TweakPreferecesController.m in Sources */,
|
||||
7D9049F91F82B6FB004E6370 /* NSString+WeChatTweak.m in Sources */,
|
||||
7DF842341F4058AB00D42D79 /* WeChatTweak.m in Sources */,
|
||||
7DB8AFBF206211D900E683AE /* WTConfigManager.m in Sources */,
|
||||
7D9049F51F82A41A004E6370 /* fishhook.c in Sources */,
|
||||
7DF8425C1F4058DD00D42D79 /* NSBundle+WeChatTweak.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
7D54A05E20E74D9400CB5306 /* TweakPreferecesController.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
7D54A05F20E74E4600CB5306 /* Base */,
|
||||
7D54A06320E74E5A00CB5306 /* en */,
|
||||
7D54A06520E74E8200CB5306 /* zh-Hans */,
|
||||
7D54A06720E74E8E00CB5306 /* zh-Hant */,
|
||||
);
|
||||
name = TweakPreferecesController.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7D54A06C20E74FE500CB5306 /* Localizable.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
7D54A07020E74FFD00CB5306 /* en */,
|
||||
7D54A07120E7535F00CB5306 /* zh-Hans */,
|
||||
7D54A07220E7536300CB5306 /* zh-Hant */,
|
||||
);
|
||||
name = Localizable.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
7DF8422D1F40583F00D42D79 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
|
@ -345,7 +401,7 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.12;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
|
@ -358,21 +414,30 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
|
@ -390,7 +455,7 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.12;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = macosx;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
|
@ -409,9 +474,10 @@
|
|||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_VERSION = A;
|
||||
INFOPLIST_FILE = WeChatTweak/Info.plist;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/WeChatTweak/Supporting Files/Info.plist";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = net.sunnyyoung.WeChatTweak;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
|
@ -429,9 +495,10 @@
|
|||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_VERSION = A;
|
||||
INFOPLIST_FILE = WeChatTweak/Info.plist;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/WeChatTweak/Supporting Files/Info.plist";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = net.sunnyyoung.WeChatTweak;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -11,5 +11,6 @@
|
|||
@interface NSBundle (WeChatTweak)
|
||||
|
||||
+ (instancetype)tweakBundle;
|
||||
- (NSString *)localizedStringForKey:(NSString *)key;
|
||||
|
||||
@end
|
|
@ -14,4 +14,8 @@
|
|||
return [NSBundle bundleWithIdentifier:@"net.sunnyyoung.WeChatTweak"];
|
||||
}
|
||||
|
||||
- (NSString *)localizedStringForKey:(NSString *)key {
|
||||
return [self localizedStringForKey:key value:nil table:nil];
|
||||
}
|
||||
|
||||
@end
|
143
WeChatTweak/Controller/Base.lproj/TweakPreferecesController.xib
Normal file
143
WeChatTweak/Controller/Base.lproj/TweakPreferecesController.xib
Normal file
|
@ -0,0 +1,143 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14113" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14113"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="TweakPreferecesController">
|
||||
<connections>
|
||||
<outlet property="autoAuthButton" destination="5by-EJ-3f2" id="VIV-sZ-ybx"/>
|
||||
<outlet property="compressedJSONEnabledButton" destination="ylY-lF-oFq" id="yqW-Bl-hNf"/>
|
||||
<outlet property="notificationTypeButton" destination="6x2-KV-p8w" id="Kfn-2a-Yup"/>
|
||||
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView id="Hz6-mo-xeY">
|
||||
<rect key="frame" x="0.0" y="0.0" width="430" height="123"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="RFE-oR-GRm">
|
||||
<rect key="frame" x="58" y="86" width="130" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" refusesFirstResponder="YES" sendsActionOnEndEditing="YES" alignment="right" title="Auto login:" usesSingleLineMode="YES" id="UiV-zj-l6I">
|
||||
<font key="font" size="13" name=".PingFangSC-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="B87-eD-uhI">
|
||||
<rect key="frame" x="10" y="53" width="178" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" refusesFirstResponder="YES" sendsActionOnEndEditing="YES" alignment="right" title="Message recall notification:" usesSingleLineMode="YES" id="UKv-CM-nGt">
|
||||
<font key="font" size="13" name=".PingFangSC-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5by-EJ-3f2">
|
||||
<rect key="frame" x="192" y="81" width="90" height="26"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Disabled" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="axesIndependently" inset="2" selectedItem="Vcv-eD-OM9" id="8qB-Jj-tlv">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="sFO-8T-61S">
|
||||
<items>
|
||||
<menuItem title="Disabled" state="on" id="Vcv-eD-OM9">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Enabled" id="KQg-jN-y9a">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="switchAutoAuthAction:" target="-2" id="P6Q-aT-ADE"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6x2-KV-p8w">
|
||||
<rect key="frame" x="192" y="48" width="91" height="26"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Inherited" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="axesIndependently" inset="2" selectedItem="gec-CY-E1x" id="wek-GT-N5V">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="H2J-gJ-aGD">
|
||||
<items>
|
||||
<menuItem title="Inherited" state="on" id="gec-CY-E1x">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="All" id="da4-aJ-lEy">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Disabled" id="Uk9-Oc-Jtv">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="switchNotificationTypeAction:" target="-2" id="xjO-Ck-wem"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="zsd-Bb-6l4">
|
||||
<rect key="frame" x="18" y="20" width="170" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" refusesFirstResponder="YES" sendsActionOnEndEditing="YES" alignment="right" title="Alfred JSON compressing:" usesSingleLineMode="YES" id="jHw-2a-B2t">
|
||||
<font key="font" size="13" name=".PingFangSC-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ylY-lF-oFq">
|
||||
<rect key="frame" x="192" y="15" width="90" height="26"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Disabled" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="axesIndependently" inset="2" selectedItem="MEN-Kg-wfj" id="taL-8q-Quu">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="2qr-A3-Yo5">
|
||||
<items>
|
||||
<menuItem title="Enabled" id="10G-t9-s4T">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Disabled" state="on" id="MEN-Kg-wfj">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="switchCompressedJSONEnabledAction:" target="-2" id="HLt-oc-7An"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="kNm-y0-HmG">
|
||||
<rect key="frame" x="287" y="20" width="100" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" refusesFirstResponder="YES" sendsActionOnEndEditing="YES" title="Need to restart" usesSingleLineMode="YES" id="2vl-mc-m3L">
|
||||
<font key="font" size="13" name=".PingFangSC-Regular"/>
|
||||
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="B87-eD-uhI" firstAttribute="trailing" secondItem="RFE-oR-GRm" secondAttribute="trailing" id="3p1-WF-TYr"/>
|
||||
<constraint firstItem="zsd-Bb-6l4" firstAttribute="top" secondItem="B87-eD-uhI" secondAttribute="bottom" constant="16" id="62W-9V-E2u"/>
|
||||
<constraint firstItem="RFE-oR-GRm" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" id="CWK-cO-DBz"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="5by-EJ-3f2" secondAttribute="trailing" constant="12" id="KRA-o3-Ab4"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="kNm-y0-HmG" secondAttribute="trailing" constant="12" id="Le8-Ns-wyj"/>
|
||||
<constraint firstItem="5by-EJ-3f2" firstAttribute="centerY" secondItem="RFE-oR-GRm" secondAttribute="centerY" id="QLN-KI-HUD"/>
|
||||
<constraint firstItem="RFE-oR-GRm" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="60" id="R8y-0p-4Sk"/>
|
||||
<constraint firstItem="B87-eD-uhI" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="12" id="TgK-yZ-mK1"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="6x2-KV-p8w" secondAttribute="trailing" constant="12" id="VbQ-1W-cmx"/>
|
||||
<constraint firstItem="6x2-KV-p8w" firstAttribute="leading" secondItem="5by-EJ-3f2" secondAttribute="leading" id="WSG-53-r8r"/>
|
||||
<constraint firstItem="zsd-Bb-6l4" firstAttribute="trailing" secondItem="RFE-oR-GRm" secondAttribute="trailing" id="Wlh-6X-UJN"/>
|
||||
<constraint firstItem="kNm-y0-HmG" firstAttribute="centerY" secondItem="ylY-lF-oFq" secondAttribute="centerY" id="eMk-RJ-Mbw"/>
|
||||
<constraint firstItem="6x2-KV-p8w" firstAttribute="centerY" secondItem="B87-eD-uhI" secondAttribute="centerY" id="gqp-om-e0O"/>
|
||||
<constraint firstItem="ylY-lF-oFq" firstAttribute="centerY" secondItem="zsd-Bb-6l4" secondAttribute="centerY" id="h7g-u6-ZwV"/>
|
||||
<constraint firstItem="zsd-Bb-6l4" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="12" id="icK-YZ-ZLo"/>
|
||||
<constraint firstItem="B87-eD-uhI" firstAttribute="top" secondItem="RFE-oR-GRm" secondAttribute="bottom" constant="16" id="lG1-vw-epo"/>
|
||||
<constraint firstItem="kNm-y0-HmG" firstAttribute="leading" secondItem="ylY-lF-oFq" secondAttribute="trailing" constant="10" id="urr-9v-Okd"/>
|
||||
<constraint firstItem="5by-EJ-3f2" firstAttribute="leading" secondItem="RFE-oR-GRm" secondAttribute="trailing" constant="8" id="v9V-TW-Voc"/>
|
||||
<constraint firstItem="ylY-lF-oFq" firstAttribute="leading" secondItem="5by-EJ-3f2" secondAttribute="leading" id="wQB-cU-fmf"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="139" y="179.5"/>
|
||||
</customView>
|
||||
</objects>
|
||||
</document>
|
|
@ -8,11 +8,13 @@
|
|||
|
||||
#import "TweakPreferecesController.h"
|
||||
#import "NSBundle+WeChatTweak.h"
|
||||
#import "WTConfigManager.h"
|
||||
|
||||
@interface TweakPreferecesController () <MASPreferencesViewController>
|
||||
|
||||
@property (weak) IBOutlet NSPopUpButton *autoAuthButton;
|
||||
@property (weak) IBOutlet NSPopUpButton *notificationTypeButton;
|
||||
@property (weak) IBOutlet NSPopUpButton *compressedJSONEnabledButton;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -28,11 +30,13 @@
|
|||
}
|
||||
|
||||
- (void)reloadData {
|
||||
WTConfigManager *configManager = WTConfigManager.sharedInstance;
|
||||
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
|
||||
BOOL enabledAutoAuth = [userDefaults boolForKey:WeChatTweakPreferenceAutoAuthKey];
|
||||
RevokeNotificationType notificationType = [userDefaults integerForKey:WeChatTweakPreferenceRevokeNotificationTypeKey];
|
||||
[self.autoAuthButton selectItemAtIndex:enabledAutoAuth ? 1 : 0];
|
||||
[self.notificationTypeButton selectItemAtIndex:notificationType];
|
||||
[self.compressedJSONEnabledButton selectItemAtIndex:configManager.compressedJSONEnabled ? 0 : 1];
|
||||
}
|
||||
|
||||
#pragma mark - Event method
|
||||
|
@ -48,6 +52,11 @@
|
|||
[[NSUserDefaults standardUserDefaults] setInteger:type forKey:WeChatTweakPreferenceRevokeNotificationTypeKey];
|
||||
}
|
||||
|
||||
- (IBAction)switchCompressedJSONEnabledAction:(NSPopUpButton *)sender {
|
||||
BOOL enabled = sender.indexOfSelectedItem == 0;
|
||||
WTConfigManager.sharedInstance.compressedJSONEnabled = enabled;
|
||||
}
|
||||
|
||||
#pragma mark - MASPreferencesViewController
|
||||
|
||||
- (NSString *)identifier {
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
/* Class = "NSMenuItem"; title = "Enabled"; ObjectID = "10G-t9-s4T"; */
|
||||
"10G-t9-s4T.title" = "Enabled";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Need to restart"; ObjectID = "2vl-mc-m3L"; */
|
||||
"2vl-mc-m3L.title" = "Need to restart";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Enabled"; ObjectID = "KQg-jN-y9a"; */
|
||||
"KQg-jN-y9a.title" = "Enabled";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Disabled"; ObjectID = "MEN-Kg-wfj"; */
|
||||
"MEN-Kg-wfj.title" = "Disabled";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Message recall notification:"; ObjectID = "UKv-CM-nGt"; */
|
||||
"UKv-CM-nGt.title" = "Message recall notification:";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Auto login:"; ObjectID = "UiV-zj-l6I"; */
|
||||
"UiV-zj-l6I.title" = "Auto login:";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Disabled"; ObjectID = "Uk9-Oc-Jtv"; */
|
||||
"Uk9-Oc-Jtv.title" = "Disabled";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Disabled"; ObjectID = "Vcv-eD-OM9"; */
|
||||
"Vcv-eD-OM9.title" = "Disabled";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "All"; ObjectID = "da4-aJ-lEy"; */
|
||||
"da4-aJ-lEy.title" = "All";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Inherited"; ObjectID = "gec-CY-E1x"; */
|
||||
"gec-CY-E1x.title" = "Inherited";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Alfred JSON compressing:"; ObjectID = "jHw-2a-B2t"; */
|
||||
"jHw-2a-B2t.title" = "Alfred JSON compressing:";
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
/* Class = "NSMenuItem"; title = "Enabled"; ObjectID = "10G-t9-s4T"; */
|
||||
"10G-t9-s4T.title" = "开启";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Need to restart"; ObjectID = "2vl-mc-m3L"; */
|
||||
"2vl-mc-m3L.title" = "需重启客户端";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Enabled"; ObjectID = "KQg-jN-y9a"; */
|
||||
"KQg-jN-y9a.title" = "开启";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Disabled"; ObjectID = "MEN-Kg-wfj"; */
|
||||
"MEN-Kg-wfj.title" = "关闭";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Message recall notification:"; ObjectID = "UKv-CM-nGt"; */
|
||||
"UKv-CM-nGt.title" = "消息撤回通知:";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Auto login:"; ObjectID = "UiV-zj-l6I"; */
|
||||
"UiV-zj-l6I.title" = "免认证登录:";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Disabled"; ObjectID = "Uk9-Oc-Jtv"; */
|
||||
"Uk9-Oc-Jtv.title" = "关闭";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Disabled"; ObjectID = "Vcv-eD-OM9"; */
|
||||
"Vcv-eD-OM9.title" = "关闭";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "All"; ObjectID = "da4-aJ-lEy"; */
|
||||
"da4-aJ-lEy.title" = "全部接收";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Inherited"; ObjectID = "gec-CY-E1x"; */
|
||||
"gec-CY-E1x.title" = "跟随聊天设置";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Alfred JSON compressing:"; ObjectID = "jHw-2a-B2t"; */
|
||||
"jHw-2a-B2t.title" = "Alfred JSON 压缩:";
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
/* Class = "NSMenuItem"; title = "Enabled"; ObjectID = "10G-t9-s4T"; */
|
||||
"10G-t9-s4T.title" = "開啟";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Need to restart"; ObjectID = "2vl-mc-m3L"; */
|
||||
"2vl-mc-m3L.title" = "需重啟客戶端";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Enabled"; ObjectID = "KQg-jN-y9a"; */
|
||||
"KQg-jN-y9a.title" = "開啟";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Disabled"; ObjectID = "MEN-Kg-wfj"; */
|
||||
"MEN-Kg-wfj.title" = "關閉";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Message recall notification:"; ObjectID = "UKv-CM-nGt"; */
|
||||
"UKv-CM-nGt.title" = "消息撤回通知:";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Auto login:"; ObjectID = "UiV-zj-l6I"; */
|
||||
"UiV-zj-l6I.title" = "免認證登錄:";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Disabled"; ObjectID = "Uk9-Oc-Jtv"; */
|
||||
"Uk9-Oc-Jtv.title" = "關閉";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Disabled"; ObjectID = "Vcv-eD-OM9"; */
|
||||
"Vcv-eD-OM9.title" = "關閉";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "All"; ObjectID = "da4-aJ-lEy"; */
|
||||
"da4-aJ-lEy.title" = "全部接收";
|
||||
|
||||
/* Class = "NSMenuItem"; title = "Inherited"; ObjectID = "gec-CY-E1x"; */
|
||||
"gec-CY-E1x.title" = "跟隨聊天設置";
|
||||
|
||||
/* Class = "NSTextFieldCell"; title = "Alfred JSON compressing:"; ObjectID = "jHw-2a-B2t"; */
|
||||
"jHw-2a-B2t.title" = "Alfred JSON 壓縮:";
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
@implementation AlfredManager
|
||||
|
||||
static int port = 48065;
|
||||
|
||||
+ (instancetype)sharedInstance {
|
||||
static dispatch_once_t onceToken;
|
||||
static AlfredManager *shared;
|
||||
|
@ -34,19 +36,27 @@
|
|||
// Search contancts
|
||||
[self.server addHandlerForMethod:@"GET" path:@"/wechat/search" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse * _Nullable(__kindof GCDWebServerRequest * _Nonnull request) {
|
||||
NSString *keyword = [request.query[@"keyword"] lowercaseString] ? : @"";
|
||||
|
||||
NSString *hostname = request.headers[@"Host"];
|
||||
NSString *url1 = [NSString stringWithFormat:@"127.0.0.1:%d", port];
|
||||
NSString *url2 = [NSString stringWithFormat:@"localhost:%d", port];
|
||||
if(!([hostname isEqualToString:url1] | [hostname isEqualToString:url2])){
|
||||
return [GCDWebServerResponse responseWithStatusCode:404];
|
||||
}
|
||||
|
||||
NSArray<WCContactData *> *contacts = ({
|
||||
MMServiceCenter *serviceCenter = [objc_getClass("MMServiceCenter") defaultCenter];
|
||||
ContactStorage *contactStorage = [serviceCenter getService:objc_getClass("ContactStorage")];
|
||||
GroupStorage *groupStorage = [serviceCenter getService:objc_getClass("GroupStorage")];
|
||||
NSMutableArray<WCContactData *> *array = [NSMutableArray array];
|
||||
[array addObjectsFromArray:[contactStorage GetAllFriendContacts]];
|
||||
[array addObjectsFromArray:[groupStorage GetAllGroups]];
|
||||
[array addObjectsFromArray:[groupStorage GetGroupContactList:2 ContactType:0]];
|
||||
array;
|
||||
});
|
||||
NSArray<WCContactData *> *results = ({
|
||||
NSMutableArray<WCContactData *> *results = [NSMutableArray array];
|
||||
for (WCContactData *contact in contacts) {
|
||||
BOOL isFriend = contact.m_uiBrandSubscriptionSettings == 0;
|
||||
BOOL isOfficialAccount = (contact.m_uiCertificationFlag >> 0x3 & 0x1) == 1;
|
||||
BOOL containsNickName = [contact.m_nsNickName.lowercaseString containsString:keyword];
|
||||
BOOL containsUsername = [contact.m_nsUsrName.lowercaseString containsString:keyword];
|
||||
BOOL containsAliasName = [contact.m_nsAliasName.lowercaseString containsString:keyword];
|
||||
|
@ -54,7 +64,7 @@
|
|||
BOOL containsNickNamePinyin = [contact.m_nsFullPY.lowercaseString containsString:keyword];
|
||||
BOOL containsRemarkPinyin = [contact.m_nsRemarkPYFull.lowercaseString containsString:keyword];
|
||||
BOOL matchRemarkShortPinyin = [contact.m_nsRemarkPYShort.lowercaseString isEqualToString:keyword];
|
||||
if (isFriend && (containsNickName || containsUsername || containsAliasName || containsRemark || containsNickNamePinyin || containsRemarkPinyin || matchRemarkShortPinyin)) {
|
||||
if (!isOfficialAccount && (containsNickName || containsUsername || containsAliasName || containsRemark || containsNickNamePinyin || containsRemarkPinyin || matchRemarkShortPinyin)) {
|
||||
[results addObject:contact];
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +74,14 @@
|
|||
}];
|
||||
// Start chat
|
||||
[self.server addHandlerForMethod:@"GET" path:@"/wechat/start" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse * _Nullable(__kindof GCDWebServerRequest * _Nonnull request) {
|
||||
|
||||
NSString *hostname = request.headers[@"Host"];
|
||||
NSString *url1 = [NSString stringWithFormat:@"127.0.0.1:%d", port];
|
||||
NSString *url2 = [NSString stringWithFormat:@"localhost:%d", port];
|
||||
if(!([hostname isEqualToString:url1] | [hostname isEqualToString:url2])){
|
||||
return [GCDWebServerResponse responseWithStatusCode:404];
|
||||
}
|
||||
|
||||
WCContactData *contact = ({
|
||||
NSString *session = request.query[@"session"];
|
||||
WCContactData *contact = nil;
|
||||
|
@ -86,7 +104,7 @@
|
|||
});
|
||||
return [GCDWebServerResponse responseWithStatusCode:200];
|
||||
}];
|
||||
[self.server startWithOptions:@{GCDWebServerOption_Port: @(48065),
|
||||
[self.server startWithOptions:@{GCDWebServerOption_Port: [NSNumber numberWithInt:port],
|
||||
GCDWebServerOption_BindToLocalhost: @(YES)} error:nil];
|
||||
}
|
||||
|
19
WeChatTweak/Manager/WTConfigManager.h
Normal file
19
WeChatTweak/Manager/WTConfigManager.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// WTConfigManager.h
|
||||
// WeChatTweak
|
||||
//
|
||||
// Created by Sunny Young on 21/03/2018.
|
||||
// Copyright © 2018 Sunnyyoung. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <objc/runtime.h>
|
||||
#import <objc/message.h>
|
||||
|
||||
@interface WTConfigManager : NSObject
|
||||
|
||||
@property (nonatomic, assign) BOOL compressedJSONEnabled;
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
|
||||
@end
|
49
WeChatTweak/Manager/WTConfigManager.m
Normal file
49
WeChatTweak/Manager/WTConfigManager.m
Normal file
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// WTConfigManager.m
|
||||
// WeChatTweak
|
||||
//
|
||||
// Created by Sunny Young on 21/03/2018.
|
||||
// Copyright © 2018 Sunnyyoung. All rights reserved.
|
||||
//
|
||||
|
||||
#import "WTConfigManager.h"
|
||||
|
||||
static NSString * const WeChatTweakCompressedJSONEnabledKey = @"WeChatTweakCompressedJSONEnabledKey";
|
||||
|
||||
@interface WTConfigManager()
|
||||
|
||||
@end
|
||||
|
||||
@implementation WTConfigManager
|
||||
|
||||
+ (instancetype)sharedInstance {
|
||||
static dispatch_once_t onceToken;
|
||||
static WTConfigManager *shared;
|
||||
dispatch_once(&onceToken, ^{
|
||||
shared = [[WTConfigManager alloc] init];
|
||||
});
|
||||
return shared;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
NSUserDefaults *userDefaults = NSUserDefaults.standardUserDefaults;
|
||||
if ([userDefaults objectForKey:WeChatTweakCompressedJSONEnabledKey]) {
|
||||
_compressedJSONEnabled = [userDefaults boolForKey:WeChatTweakCompressedJSONEnabledKey];
|
||||
} else {
|
||||
_compressedJSONEnabled = YES;
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Property method
|
||||
|
||||
- (void)setCompressedJSONEnabled:(BOOL)compressedJSONEnabled {
|
||||
_compressedJSONEnabled = compressedJSONEnabled;
|
||||
[NSUserDefaults.standardUserDefaults setBool:compressedJSONEnabled forKey:WeChatTweakCompressedJSONEnabledKey];
|
||||
[NSUserDefaults.standardUserDefaults synchronize];
|
||||
}
|
||||
|
||||
@end
|
|
@ -8,9 +8,19 @@
|
|||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <objc/runtime.h>
|
||||
#import <objc/message.h>
|
||||
|
||||
@interface NSString (MD5)
|
||||
|
||||
- (NSString *)md5String;
|
||||
|
||||
@end
|
||||
|
||||
@interface WeChat : NSObject
|
||||
|
||||
@property(nonatomic) BOOL isAppTerminating;
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
- (void)lock:(id)block;
|
||||
- (void)showMainWindow;
|
||||
|
@ -18,6 +28,12 @@
|
|||
|
||||
@end
|
||||
|
||||
@interface PathUtility : NSObject
|
||||
|
||||
+ (NSString *)GetCurUserDocumentPath;
|
||||
|
||||
@end
|
||||
|
||||
@interface MMSearchResultItem : NSObject
|
||||
|
||||
@property(nonatomic) unsigned long long type; // 0 is single chat, 1 is group chat
|
||||
|
@ -29,19 +45,22 @@
|
|||
|
||||
@property(nonatomic) unsigned int messageType;
|
||||
@property(nonatomic) unsigned int msgStatus;
|
||||
@property(nonatomic) long long mesSvrID;
|
||||
@property(retain, nonatomic) NSString *toUsrName;
|
||||
@property(retain, nonatomic) NSString *fromUsrName;
|
||||
@property(retain, nonatomic) NSString *msgContent;
|
||||
@property(nonatomic) unsigned int msgCreateTime;
|
||||
@property(nonatomic) unsigned int mesLocalID;
|
||||
|
||||
- (instancetype)initWithMsgType:(long long)arg1;
|
||||
- (BOOL)isSendFromSelf;
|
||||
|
||||
@end
|
||||
|
||||
@interface WCContactData : NSObject
|
||||
|
||||
@property(nonatomic) unsigned int m_uiBrandSubscriptionSettings;
|
||||
@property(nonatomic) unsigned int m_uiCertificationFlag;
|
||||
@property(retain, nonatomic) NSString *m_nsHeadImgUrl;
|
||||
@property(retain, nonatomic) NSString *m_nsNickName;
|
||||
@property(retain, nonatomic) NSString *m_nsUsrName;
|
||||
@property(retain, nonatomic) NSString *m_nsAliasName;
|
||||
|
@ -49,6 +68,7 @@
|
|||
@property(retain, nonatomic) NSString *m_nsFullPY;
|
||||
@property(retain, nonatomic) NSString *m_nsRemarkPYShort;
|
||||
@property(retain, nonatomic) NSString *m_nsRemarkPYFull;
|
||||
@property(retain, nonatomic) NSString *wt_avatarPath;
|
||||
|
||||
- (BOOL)isChatStatusNotifyOpen;
|
||||
|
||||
|
@ -65,6 +85,7 @@
|
|||
|
||||
- (WCContactData *)GetGroupContact:(NSString *)session;
|
||||
- (NSArray<WCContactData *> *)GetAllGroups;
|
||||
- (NSArray<WCContactData *> *)GetGroupContactList:(NSInteger)arg1 ContactType:(NSInteger)arg2;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -88,6 +109,19 @@
|
|||
|
||||
- (BOOL)canAutoAuth;
|
||||
- (void)AutoAuth;
|
||||
- (void)onAuthOKOfUser:(id)arg1 withSessionKey:(id)arg2 withServerId:(id)arg3 autoAuthKey:(id)arg4 isAutoAuth:(BOOL)arg5;
|
||||
|
||||
@end
|
||||
|
||||
@interface LogoutCGI: NSObject
|
||||
|
||||
- (void)sendLogoutCGIWithCompletion:(id)arg1;
|
||||
|
||||
@end
|
||||
|
||||
@interface MMAvatarService: NSObject
|
||||
|
||||
- (NSString *)avatarCachePath;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -103,7 +137,7 @@
|
|||
|
||||
@end
|
||||
|
||||
@interface MASPreferencesWindowController : NSWindowController
|
||||
@interface MASPreferencesWindowController: NSWindowController
|
||||
|
||||
- (id)initWithViewControllers:(NSArray *)arg1;
|
||||
|
11
WeChatTweak/Supporting Files/en.lproj/Localizable.strings
Normal file
11
WeChatTweak/Supporting Files/en.lproj/Localizable.strings
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
Localizable.strings
|
||||
WeChatTweak
|
||||
|
||||
Created by Sunny Young on 2018/6/30.
|
||||
Copyright © 2018 Sunnyyoung. All rights reserved.
|
||||
*/
|
||||
|
||||
"Tweak.Title.LoginAnotherAccount" = "Login new account";
|
||||
"Tweak.Title.Group" = "Group";
|
||||
"Tweak.Message.CatchARecalledMessage" = "[Catched]\n%@";
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
Localizable.strings
|
||||
WeChatTweak
|
||||
|
||||
Created by Sunny Young on 2018/6/30.
|
||||
Copyright © 2018 Sunnyyoung. All rights reserved.
|
||||
*/
|
||||
|
||||
"Tweak.Title.LoginAnotherAccount" = "登录新的账号";
|
||||
"Tweak.Title.Group" = "群组";
|
||||
"Tweak.Message.CatchARecalledMessage" = "[已拦截]\n%@";
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
Localizable.strings
|
||||
WeChatTweak
|
||||
|
||||
Created by Sunny Young on 2018/6/30.
|
||||
Copyright © 2018 Sunnyyoung. All rights reserved.
|
||||
*/
|
||||
|
||||
"Tweak.Title.LoginAnotherAccount" = "登錄新的賬號";
|
||||
"Tweak.Title.Group" = "群組";
|
||||
"Tweak.Message.CatchARecalledMessage" = "[已攔截]\n%@";
|
|
@ -1,95 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="12121"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="TweakPreferecesController">
|
||||
<connections>
|
||||
<outlet property="autoAuthButton" destination="5by-EJ-3f2" id="VIV-sZ-ybx"/>
|
||||
<outlet property="notificationTypeButton" destination="6x2-KV-p8w" id="Kfn-2a-Yup"/>
|
||||
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView id="Hz6-mo-xeY">
|
||||
<rect key="frame" x="0.0" y="0.0" width="430" height="92"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RFE-oR-GRm">
|
||||
<rect key="frame" x="58" y="55" width="111" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="免手机认证登陆:" id="UiV-zj-l6I">
|
||||
<font key="font" size="13" name=".PingFangSC-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="B87-eD-uhI">
|
||||
<rect key="frame" x="72" y="22" width="97" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="消息撤回通知:" id="UKv-CM-nGt">
|
||||
<font key="font" size="13" name=".PingFangSC-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5by-EJ-3f2">
|
||||
<rect key="frame" x="173" y="50" width="64" height="26"/>
|
||||
<popUpButtonCell key="cell" type="push" title="关闭" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="Vcv-eD-OM9" id="8qB-Jj-tlv">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="sFO-8T-61S">
|
||||
<items>
|
||||
<menuItem title="关闭" state="on" id="Vcv-eD-OM9">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="开启" id="KQg-jN-y9a">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="switchAutoAuthAction:" target="-2" id="P6Q-aT-ADE"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6x2-KV-p8w">
|
||||
<rect key="frame" x="173" y="17" width="144" height="26"/>
|
||||
<popUpButtonCell key="cell" type="push" title="跟随聊天通知设置" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="gec-CY-E1x" id="wek-GT-N5V">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="H2J-gJ-aGD">
|
||||
<items>
|
||||
<menuItem title="跟随聊天通知设置" state="on" id="gec-CY-E1x">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="全部接收" id="da4-aJ-lEy">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="全部关闭" id="Uk9-Oc-Jtv">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="switchNotificationTypeAction:" target="-2" id="xjO-Ck-wem"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="B87-eD-uhI" firstAttribute="trailing" secondItem="RFE-oR-GRm" secondAttribute="trailing" id="3p1-WF-TYr"/>
|
||||
<constraint firstItem="RFE-oR-GRm" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" id="CWK-cO-DBz"/>
|
||||
<constraint firstItem="5by-EJ-3f2" firstAttribute="centerY" secondItem="RFE-oR-GRm" secondAttribute="centerY" id="QLN-KI-HUD"/>
|
||||
<constraint firstItem="RFE-oR-GRm" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="60" id="R8y-0p-4Sk"/>
|
||||
<constraint firstItem="6x2-KV-p8w" firstAttribute="leading" secondItem="5by-EJ-3f2" secondAttribute="leading" id="WSG-53-r8r"/>
|
||||
<constraint firstItem="6x2-KV-p8w" firstAttribute="centerY" secondItem="B87-eD-uhI" secondAttribute="centerY" id="gqp-om-e0O"/>
|
||||
<constraint firstItem="B87-eD-uhI" firstAttribute="top" secondItem="RFE-oR-GRm" secondAttribute="bottom" constant="16" id="lG1-vw-epo"/>
|
||||
<constraint firstItem="5by-EJ-3f2" firstAttribute="leading" secondItem="RFE-oR-GRm" secondAttribute="trailing" constant="8" id="v9V-TW-Voc"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="139" y="164"/>
|
||||
</customView>
|
||||
</objects>
|
||||
</document>
|
210
WeChatTweak/Vendor/fishhook.c
vendored
Normal file
210
WeChatTweak/Vendor/fishhook.c
vendored
Normal file
|
@ -0,0 +1,210 @@
|
|||
// Copyright (c) 2013, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name Facebook nor the names of its contributors may be used to
|
||||
// endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#import "fishhook.h"
|
||||
|
||||
#import <dlfcn.h>
|
||||
#import <stdlib.h>
|
||||
#import <string.h>
|
||||
#import <sys/types.h>
|
||||
#import <mach-o/dyld.h>
|
||||
#import <mach-o/loader.h>
|
||||
#import <mach-o/nlist.h>
|
||||
|
||||
#ifdef __LP64__
|
||||
typedef struct mach_header_64 mach_header_t;
|
||||
typedef struct segment_command_64 segment_command_t;
|
||||
typedef struct section_64 section_t;
|
||||
typedef struct nlist_64 nlist_t;
|
||||
#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64
|
||||
#else
|
||||
typedef struct mach_header mach_header_t;
|
||||
typedef struct segment_command segment_command_t;
|
||||
typedef struct section section_t;
|
||||
typedef struct nlist nlist_t;
|
||||
#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT
|
||||
#endif
|
||||
|
||||
#ifndef SEG_DATA_CONST
|
||||
#define SEG_DATA_CONST "__DATA_CONST"
|
||||
#endif
|
||||
|
||||
struct rebindings_entry {
|
||||
struct rebinding *rebindings;
|
||||
size_t rebindings_nel;
|
||||
struct rebindings_entry *next;
|
||||
};
|
||||
|
||||
static struct rebindings_entry *_rebindings_head;
|
||||
|
||||
static int prepend_rebindings(struct rebindings_entry **rebindings_head,
|
||||
struct rebinding rebindings[],
|
||||
size_t nel) {
|
||||
struct rebindings_entry *new_entry = (struct rebindings_entry *) malloc(sizeof(struct rebindings_entry));
|
||||
if (!new_entry) {
|
||||
return -1;
|
||||
}
|
||||
new_entry->rebindings = (struct rebinding *) malloc(sizeof(struct rebinding) * nel);
|
||||
if (!new_entry->rebindings) {
|
||||
free(new_entry);
|
||||
return -1;
|
||||
}
|
||||
memcpy(new_entry->rebindings, rebindings, sizeof(struct rebinding) * nel);
|
||||
new_entry->rebindings_nel = nel;
|
||||
new_entry->next = *rebindings_head;
|
||||
*rebindings_head = new_entry;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void perform_rebinding_with_section(struct rebindings_entry *rebindings,
|
||||
section_t *section,
|
||||
intptr_t slide,
|
||||
nlist_t *symtab,
|
||||
char *strtab,
|
||||
uint32_t *indirect_symtab) {
|
||||
uint32_t *indirect_symbol_indices = indirect_symtab + section->reserved1;
|
||||
void **indirect_symbol_bindings = (void **)((uintptr_t)slide + section->addr);
|
||||
for (uint i = 0; i < section->size / sizeof(void *); i++) {
|
||||
uint32_t symtab_index = indirect_symbol_indices[i];
|
||||
if (symtab_index == INDIRECT_SYMBOL_ABS || symtab_index == INDIRECT_SYMBOL_LOCAL ||
|
||||
symtab_index == (INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS)) {
|
||||
continue;
|
||||
}
|
||||
uint32_t strtab_offset = symtab[symtab_index].n_un.n_strx;
|
||||
char *symbol_name = strtab + strtab_offset;
|
||||
if (strnlen(symbol_name, 2) < 2) {
|
||||
continue;
|
||||
}
|
||||
struct rebindings_entry *cur = rebindings;
|
||||
while (cur) {
|
||||
for (uint j = 0; j < cur->rebindings_nel; j++) {
|
||||
if (strcmp(&symbol_name[1], cur->rebindings[j].name) == 0) {
|
||||
if (cur->rebindings[j].replaced != NULL &&
|
||||
indirect_symbol_bindings[i] != cur->rebindings[j].replacement) {
|
||||
*(cur->rebindings[j].replaced) = indirect_symbol_bindings[i];
|
||||
}
|
||||
indirect_symbol_bindings[i] = cur->rebindings[j].replacement;
|
||||
goto symbol_loop;
|
||||
}
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
symbol_loop:;
|
||||
}
|
||||
}
|
||||
|
||||
static void rebind_symbols_for_image(struct rebindings_entry *rebindings,
|
||||
const struct mach_header *header,
|
||||
intptr_t slide) {
|
||||
Dl_info info;
|
||||
if (dladdr(header, &info) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
segment_command_t *cur_seg_cmd;
|
||||
segment_command_t *linkedit_segment = NULL;
|
||||
struct symtab_command* symtab_cmd = NULL;
|
||||
struct dysymtab_command* dysymtab_cmd = NULL;
|
||||
|
||||
uintptr_t cur = (uintptr_t)header + sizeof(mach_header_t);
|
||||
for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) {
|
||||
cur_seg_cmd = (segment_command_t *)cur;
|
||||
if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) {
|
||||
if (strcmp(cur_seg_cmd->segname, SEG_LINKEDIT) == 0) {
|
||||
linkedit_segment = cur_seg_cmd;
|
||||
}
|
||||
} else if (cur_seg_cmd->cmd == LC_SYMTAB) {
|
||||
symtab_cmd = (struct symtab_command*)cur_seg_cmd;
|
||||
} else if (cur_seg_cmd->cmd == LC_DYSYMTAB) {
|
||||
dysymtab_cmd = (struct dysymtab_command*)cur_seg_cmd;
|
||||
}
|
||||
}
|
||||
|
||||
if (!symtab_cmd || !dysymtab_cmd || !linkedit_segment ||
|
||||
!dysymtab_cmd->nindirectsyms) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find base symbol/string table addresses
|
||||
uintptr_t linkedit_base = (uintptr_t)slide + linkedit_segment->vmaddr - linkedit_segment->fileoff;
|
||||
nlist_t *symtab = (nlist_t *)(linkedit_base + symtab_cmd->symoff);
|
||||
char *strtab = (char *)(linkedit_base + symtab_cmd->stroff);
|
||||
|
||||
// Get indirect symbol table (array of uint32_t indices into symbol table)
|
||||
uint32_t *indirect_symtab = (uint32_t *)(linkedit_base + dysymtab_cmd->indirectsymoff);
|
||||
|
||||
cur = (uintptr_t)header + sizeof(mach_header_t);
|
||||
for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) {
|
||||
cur_seg_cmd = (segment_command_t *)cur;
|
||||
if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) {
|
||||
if (strcmp(cur_seg_cmd->segname, SEG_DATA) != 0 &&
|
||||
strcmp(cur_seg_cmd->segname, SEG_DATA_CONST) != 0) {
|
||||
continue;
|
||||
}
|
||||
for (uint j = 0; j < cur_seg_cmd->nsects; j++) {
|
||||
section_t *sect =
|
||||
(section_t *)(cur + sizeof(segment_command_t)) + j;
|
||||
if ((sect->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS) {
|
||||
perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab);
|
||||
}
|
||||
if ((sect->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS) {
|
||||
perform_rebinding_with_section(rebindings, sect, slide, symtab, strtab, indirect_symtab);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void _rebind_symbols_for_image(const struct mach_header *header,
|
||||
intptr_t slide) {
|
||||
rebind_symbols_for_image(_rebindings_head, header, slide);
|
||||
}
|
||||
|
||||
int rebind_symbols_image(void *header,
|
||||
intptr_t slide,
|
||||
struct rebinding rebindings[],
|
||||
size_t rebindings_nel) {
|
||||
struct rebindings_entry *rebindings_head = NULL;
|
||||
int retval = prepend_rebindings(&rebindings_head, rebindings, rebindings_nel);
|
||||
rebind_symbols_for_image(rebindings_head, (const struct mach_header *) header, slide);
|
||||
free(rebindings_head);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel) {
|
||||
int retval = prepend_rebindings(&_rebindings_head, rebindings, rebindings_nel);
|
||||
if (retval < 0) {
|
||||
return retval;
|
||||
}
|
||||
// If this was the first call, register callback for image additions (which is also invoked for
|
||||
// existing images, otherwise, just run on existing images
|
||||
if (!_rebindings_head->next) {
|
||||
_dyld_register_func_for_add_image(_rebind_symbols_for_image);
|
||||
} else {
|
||||
uint32_t c = _dyld_image_count();
|
||||
for (uint32_t i = 0; i < c; i++) {
|
||||
_rebind_symbols_for_image(_dyld_get_image_header(i), _dyld_get_image_vmaddr_slide(i));
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
76
WeChatTweak/Vendor/fishhook.h
vendored
Normal file
76
WeChatTweak/Vendor/fishhook.h
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
// Copyright (c) 2013, Facebook, Inc.
|
||||
// All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name Facebook nor the names of its contributors may be used to
|
||||
// endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef fishhook_h
|
||||
#define fishhook_h
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if !defined(FISHHOOK_EXPORT)
|
||||
#define FISHHOOK_VISIBILITY __attribute__((visibility("hidden")))
|
||||
#else
|
||||
#define FISHHOOK_VISIBILITY __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif //__cplusplus
|
||||
|
||||
/*
|
||||
* A structure representing a particular intended rebinding from a symbol
|
||||
* name to its replacement
|
||||
*/
|
||||
struct rebinding {
|
||||
const char *name;
|
||||
void *replacement;
|
||||
void **replaced;
|
||||
};
|
||||
|
||||
/*
|
||||
* For each rebinding in rebindings, rebinds references to external, indirect
|
||||
* symbols with the specified name to instead point at replacement for each
|
||||
* image in the calling process as well as for all future images that are loaded
|
||||
* by the process. If rebind_functions is called more than once, the symbols to
|
||||
* rebind are added to the existing list of rebindings, and if a given symbol
|
||||
* is rebound more than once, the later rebinding will take precedence.
|
||||
*/
|
||||
FISHHOOK_VISIBILITY
|
||||
int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel);
|
||||
|
||||
/*
|
||||
* Rebinds as above, but only in the specified image. The header should point
|
||||
* to the mach-o header, the slide should be the slide offset. Others as above.
|
||||
*/
|
||||
FISHHOOK_VISIBILITY
|
||||
int rebind_symbols_image(void *header,
|
||||
intptr_t slide,
|
||||
struct rebinding rebindings[],
|
||||
size_t rebindings_nel);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //__cplusplus
|
||||
|
||||
#endif //fishhook_h
|
||||
|
|
@ -8,50 +8,93 @@
|
|||
|
||||
#import "WeChatTweak.h"
|
||||
#import "WeChatTweakHeaders.h"
|
||||
#import "fishhook.h"
|
||||
#import "NSBundle+WeChatTweak.h"
|
||||
#import "NSString+WeChatTweak.h"
|
||||
#import "TweakPreferecesController.h"
|
||||
#import "AlfredManager.h"
|
||||
#import "WTConfigManager.h"
|
||||
|
||||
// Global Function
|
||||
static NSString *(*original_NSHomeDirectory)(void);
|
||||
static NSArray<NSString *> *(*original_NSSearchPathForDirectoriesInDomains)(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde);
|
||||
NSString *tweak_NSHomeDirectory() {
|
||||
return [original_NSHomeDirectory() stringByAppendingPathComponent:@"/Library/Containers/com.tencent.xinWeChat/Data/"];
|
||||
}
|
||||
NSArray<NSString *> *tweak_NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde) {
|
||||
if (domainMask == NSUserDomainMask) {
|
||||
NSMutableArray<NSString *> *directories = [original_NSSearchPathForDirectoriesInDomains(directory, domainMask, expandTilde) mutableCopy];
|
||||
[directories enumerateObjectsUsingBlock:^(NSString * _Nonnull object, NSUInteger index, BOOL * _Nonnull stop) {
|
||||
switch (directory) {
|
||||
case NSDocumentDirectory: directories[index] = [tweak_NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; break;
|
||||
case NSLibraryDirectory: directories[index] = [tweak_NSHomeDirectory() stringByAppendingPathComponent:@"Library"]; break;
|
||||
case NSApplicationSupportDirectory: directories[index] = [tweak_NSHomeDirectory() stringByAppendingPathComponent:@"Library/Application Support"]; break;
|
||||
case NSCachesDirectory: directories[index] = [tweak_NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches"]; break;
|
||||
default: break;
|
||||
}
|
||||
}];
|
||||
return directories;
|
||||
} else {
|
||||
return original_NSSearchPathForDirectoriesInDomains(directory, domainMask, expandTilde);
|
||||
}
|
||||
}
|
||||
|
||||
@implementation NSObject (WeChatTweak)
|
||||
|
||||
#pragma mark - Constructor
|
||||
|
||||
static void __attribute__((constructor)) tweak(void) {
|
||||
// Global Function Hook
|
||||
rebind_symbols((struct rebinding[2]) {
|
||||
{ "NSHomeDirectory", tweak_NSHomeDirectory, (void *)&original_NSHomeDirectory },
|
||||
{ "NSSearchPathForDirectoriesInDomains", tweak_NSSearchPathForDirectoriesInDomains, (void *)&original_NSSearchPathForDirectoriesInDomains }
|
||||
}, 2);
|
||||
// Method Swizzling
|
||||
class_addMethod(objc_getClass("AppDelegate"), @selector(applicationDockMenu:), method_getImplementation(class_getInstanceMethod(objc_getClass("AppDelegate"), @selector(tweak_applicationDockMenu:))), "@:@");
|
||||
[objc_getClass("AppDelegate") jr_swizzleMethod:NSSelectorFromString(@"applicationDidFinishLaunching:") withMethod:@selector(tweak_applicationDidFinishLaunching:) error:nil];
|
||||
[objc_getClass("AppDelegate") jr_swizzleMethod:NSSelectorFromString(@"applicationShouldTerminate:") withMethod:@selector(tweak_applicationShouldTerminate:) error:nil];
|
||||
[objc_getClass("LogoutCGI") jr_swizzleMethod:NSSelectorFromString(@"sendLogoutCGIWithCompletion:") withMethod:@selector(tweak_sendLogoutCGIWithCompletion:) error:nil];
|
||||
[objc_getClass("AccountService") jr_swizzleMethod:NSSelectorFromString(@"onAuthOKOfUser:withSessionKey:withServerId:autoAuthKey:isAutoAuth:") withMethod:@selector(tweak_onAuthOKOfUser:withSessionKey:withServerId:autoAuthKey:isAutoAuth:) error:nil];
|
||||
[objc_getClass("AccountService") jr_swizzleMethod:NSSelectorFromString(@"ManualLogout") withMethod:@selector(tweak_ManualLogout) error:nil];
|
||||
[objc_getClass("MessageService") jr_swizzleMethod:NSSelectorFromString(@"onRevokeMsg:") withMethod:@selector(tweak_onRevokeMsg:) error:nil];
|
||||
[objc_getClass("CUtility") jr_swizzleClassMethod:NSSelectorFromString(@"HasWechatInstance") withClassMethod:@selector(tweak_HasWechatInstance) error:nil];
|
||||
[objc_getClass("MASPreferencesWindowController") jr_swizzleMethod:NSSelectorFromString(@"initWithViewControllers:") withMethod:@selector(tweak_initWithViewControllers:) error:nil];
|
||||
|
||||
objc_property_attribute_t type = { "T", "@\"NSString\"" }; // NSString
|
||||
objc_property_attribute_t atom = { "N", "" }; // nonatomic
|
||||
objc_property_attribute_t ownership = { "&", "" }; // C = copy & = strong
|
||||
objc_property_attribute_t backingivar = { "V", "_m_nsHeadImgUrl" }; // ivar name
|
||||
objc_property_attribute_t attrs[] = { type, atom, ownership, backingivar };
|
||||
class_addProperty(objc_getClass("WCContactData"), "wt_avatarPath", attrs, 4);
|
||||
class_addMethod(objc_getClass("WCContactData"), @selector(wt_avatarPath), method_getImplementation(class_getInstanceMethod(objc_getClass("WCContactData"), @selector(wt_avatarPath))), "@@:");
|
||||
class_addMethod(objc_getClass("WCContactData"), @selector(setWt_avatarPath:), method_getImplementation(class_getInstanceMethod(objc_getClass("WCContactData"), @selector(setWt_avatarPath:))), "v@:@");
|
||||
class_addMethod(objc_getClass("WCContactData"), @selector(modelPropertyWhitelist), method_getImplementation(class_getClassMethod(objc_getClass("WCContactData"), @selector(modelPropertyWhitelist))), "v@:");
|
||||
}
|
||||
|
||||
#pragma mark - No Revoke Message
|
||||
|
||||
- (void)tweak_onRevokeMsg:(NSString *)message {
|
||||
- (void)tweak_onRevokeMsg:(MessageData *)message {
|
||||
// Decode message
|
||||
NSString *session = [message tweak_subStringFrom:@"<session>" to:@"</session>"];
|
||||
NSUInteger newMessageID = [message tweak_subStringFrom:@"<newmsgid>" to:@"</newmsgid>"].longLongValue;
|
||||
NSString *replaceMessage = [message tweak_subStringFrom:@"<replacemsg><![CDATA[" to:@"]]></replacemsg>"];
|
||||
|
||||
NSString *session = [message.msgContent tweak_subStringFrom:@"<session>" to:@"</session>"];
|
||||
NSUInteger newMessageID = [message.msgContent tweak_subStringFrom:@"<newmsgid>" to:@"</newmsgid>"].longLongValue;
|
||||
NSString *replaceMessage = [message.msgContent tweak_subStringFrom:@"<replacemsg><![CDATA[" to:@"]]></replacemsg>"];
|
||||
// Prepare message data
|
||||
MessageData *localMessageData = [((MessageService *)self) GetMsgData:session svrId:newMessageID];
|
||||
MessageData *promptMessageData = ({
|
||||
MessageData *data = [[objc_getClass("MessageData") alloc] init];
|
||||
data.messageType = 10000;
|
||||
MessageData *data = [[objc_getClass("MessageData") alloc] initWithMsgType:10000];
|
||||
data.msgStatus = 4;
|
||||
data.toUsrName = localMessageData.toUsrName;
|
||||
data.fromUsrName = localMessageData.fromUsrName;
|
||||
data.mesSvrID = localMessageData.mesSvrID;
|
||||
data.mesLocalID = localMessageData.mesLocalID;
|
||||
data.msgCreateTime = localMessageData.msgCreateTime;
|
||||
if ([localMessageData isSendFromSelf]) {
|
||||
data.msgContent = replaceMessage;
|
||||
} else {
|
||||
data.msgContent = [NSString stringWithFormat:@"[已拦截]\n%@", replaceMessage];
|
||||
data.msgContent = [NSString stringWithFormat:[NSBundle.tweakBundle localizedStringForKey:@"Tweak.Message.CatchARecalledMessage"], replaceMessage];
|
||||
}
|
||||
data;
|
||||
});
|
||||
|
||||
|
||||
// Prepare notification information
|
||||
MMServiceCenter *serviceCenter = [objc_getClass("MMServiceCenter") defaultCenter];
|
||||
NSUserNotification *userNotification = [[NSUserNotification alloc] init];
|
||||
|
@ -65,19 +108,20 @@ static void __attribute__((constructor)) tweak(void) {
|
|||
GroupStorage *groupStorage = [serviceCenter getService:objc_getClass("GroupStorage")];
|
||||
WCContactData *groupContact = [groupStorage GetGroupContact:session];
|
||||
isChatStatusNotifyOpen = [groupContact isChatStatusNotifyOpen];
|
||||
NSString *groupName = groupContact.m_nsNickName.length ? groupContact.m_nsNickName : @"群组";
|
||||
NSString *groupName = groupContact.m_nsNickName.length ? groupContact.m_nsNickName : [NSBundle.tweakBundle localizedStringForKey:@"Tweak.Title.Group"];
|
||||
userNotification.informativeText = [NSString stringWithFormat:@"%@: %@", groupName, replaceMessage];
|
||||
}
|
||||
|
||||
|
||||
// Delete message if it is revoke from myself
|
||||
if ([localMessageData isSendFromSelf]) {
|
||||
[((MessageService *)self) DelMsg:session msgList:@[localMessageData] isDelAll:NO isManual:YES];
|
||||
[((MessageService *)self) AddLocalMsg:session msgData:promptMessageData];
|
||||
} else {
|
||||
[((MessageService *)self) AddLocalMsg:session msgData:promptMessageData];
|
||||
}
|
||||
|
||||
// Dispatch notification
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
// Delete message if it is revoke from myself
|
||||
if ([localMessageData isSendFromSelf]) {
|
||||
[((MessageService *)self) DelMsg:session msgList:@[localMessageData] isDelAll:NO isManual:YES];
|
||||
[((MessageService *)self) AddLocalMsg:session msgData:promptMessageData];
|
||||
} else {
|
||||
[((MessageService *)self) AddLocalMsg:session msgData:promptMessageData];
|
||||
}
|
||||
// Deliver notification
|
||||
if (![localMessageData isSendFromSelf]) {
|
||||
RevokeNotificationType notificationType = [[NSUserDefaults standardUserDefaults] integerForKey:WeChatTweakPreferenceRevokeNotificationTypeKey];
|
||||
|
@ -96,7 +140,9 @@ static void __attribute__((constructor)) tweak(void) {
|
|||
|
||||
- (NSMenu *)tweak_applicationDockMenu:(NSApplication *)sender {
|
||||
NSMenu *menu = [[NSMenu alloc] init];
|
||||
NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:@"登录新的微信账号" action:@selector(openNewWeChatInstace:) keyEquivalent:@""];
|
||||
NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:[NSBundle.tweakBundle localizedStringForKey:@"Tweak.Title.LoginAnotherAccount"]
|
||||
action:@selector(openNewWeChatInstace:)
|
||||
keyEquivalent:@""];
|
||||
[menu insertItem:menuItem atIndex:0];
|
||||
return menu;
|
||||
}
|
||||
|
@ -124,15 +170,26 @@ static void __attribute__((constructor)) tweak(void) {
|
|||
[accountService AutoAuth];
|
||||
}
|
||||
}
|
||||
[[AlfredManager sharedInstance] startListener];
|
||||
}
|
||||
|
||||
- (NSApplicationTerminateReply)tweak_applicationShouldTerminate:(NSApplication *)sender {
|
||||
- (void)tweak_onAuthOKOfUser:(id)arg1 withSessionKey:(id)arg2 withServerId:(id)arg3 autoAuthKey:(id)arg4 isAutoAuth:(BOOL)arg5 {
|
||||
[[AlfredManager sharedInstance] startListener];
|
||||
[self tweak_onAuthOKOfUser:arg1 withSessionKey:arg2 withServerId:arg3 autoAuthKey:arg4 isAutoAuth:arg5];
|
||||
}
|
||||
|
||||
- (void)tweak_sendLogoutCGIWithCompletion:(id)completion {
|
||||
BOOL enabledAutoAuth = [[NSUserDefaults standardUserDefaults] boolForKey:WeChatTweakPreferenceAutoAuthKey];
|
||||
if (enabledAutoAuth) {
|
||||
return NSTerminateNow;
|
||||
} else {
|
||||
return [self tweak_applicationShouldTerminate:sender];
|
||||
WeChat *wechat = [objc_getClass("WeChat") sharedInstance];
|
||||
if (enabledAutoAuth && wechat.isAppTerminating) {
|
||||
return;
|
||||
}
|
||||
[self tweak_sendLogoutCGIWithCompletion:completion];
|
||||
}
|
||||
|
||||
- (void)tweak_ManualLogout {
|
||||
BOOL enabledAutoAuth = [[NSUserDefaults standardUserDefaults] boolForKey:WeChatTweakPreferenceAutoAuthKey];
|
||||
if (!enabledAutoAuth) {
|
||||
[self tweak_ManualLogout];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,4 +202,27 @@ static void __attribute__((constructor)) tweak(void) {
|
|||
return [self tweak_initWithViewControllers:viewControllers];
|
||||
}
|
||||
|
||||
#pragma mark - WCContact Data
|
||||
|
||||
- (NSString *)wt_avatarPath {
|
||||
if (![objc_getClass("PathUtility") respondsToSelector:@selector(GetCurUserDocumentPath)]) {
|
||||
return @"";
|
||||
}
|
||||
NSString *pathString = [NSString stringWithFormat:@"%@/Avatar/%@.jpg", [objc_getClass("PathUtility") GetCurUserDocumentPath], [((WCContactData *)self).m_nsUsrName md5String]];
|
||||
return [NSFileManager.defaultManager fileExistsAtPath:pathString] ? pathString : @"";
|
||||
}
|
||||
|
||||
- (void)setWt_avatarPath:(NSString *)avatarPath {
|
||||
// For readonly
|
||||
return;
|
||||
}
|
||||
|
||||
+ (NSArray *)modelPropertyWhitelist {
|
||||
NSArray *list =@[@"wt_avatarPath",
|
||||
@"m_nsRemark",
|
||||
@"m_nsNickName",
|
||||
@"m_nsUsrName"];
|
||||
return WTConfigManager.sharedInstance.compressedJSONEnabled ? list : nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
1
_config.yml
Normal file
1
_config.yml
Normal file
|
@ -0,0 +1 @@
|
|||
theme: jekyll-theme-cayman
|
Loading…
Reference in New Issue
Block a user