Compatible with WeChat 3.7.1

1. Upgrade dependencies
2. Update project settings
3. Remvoe classic revoked message style
This commit is contained in:
Sunny Young
2023-04-28 11:11:18 +08:00
parent 0b8de8dc63
commit 2606dcf88c
15 changed files with 60 additions and 246 deletions
+6 -92
View File
@@ -13,7 +13,7 @@
static void __attribute__((constructor)) tweak(void) {
[objc_getClass("FFProcessReqsvrZZ") jr_swizzleMethod:NSSelectorFromString(@"FFToNameFavChatZZ:sessionMsgList:") withMethod:@selector(tweak_FFToNameFavChatZZ:sessionMsgList:) error:nil];
[objc_getClass("MMMessageCellView") jr_swizzleMethod:NSSelectorFromString(@"initWithFrame:") withMethod:@selector(tweak_initWithFrame:) error:nil];
[objc_getClass("MMMessageCellView") jr_swizzleMethod:NSSelectorFromString(@"populateWithMessage:") withMethod:@selector(tweak_populateWithMessage:) error:nil];
[objc_getClass("MMMessageCellView") jr_swizzleMethod:NSSelectorFromString(@"layout") withMethod:@selector(tweak_layout) error:nil];
@@ -27,7 +27,7 @@ static void __attribute__((constructor)) tweak(void) {
return [self tweak_FFToNameFavChatZZ:message sessionMsgList:sessionMsgList];
}
// Decode message
NSDictionary *dictionary = [NSDictionary dictionaryWithXMLString:[message.msgContent componentsSeparatedByCharactersInSet:NSCharacterSet.newlineCharacterSet].lastObject];
NSDictionary *dictionary = [NSDictionary dictionaryWithXMLString:message.msgContent];
NSString *session = dictionary[@"revokemsg"][@"session"];
NSString *newMessageID = dictionary[@"revokemsg"][@"newmsgid"];
NSString *replaceMessage = dictionary[@"revokemsg"][@"replacemsg"];
@@ -37,97 +37,11 @@ static void __attribute__((constructor)) tweak(void) {
// Fallback to origin method
[self tweak_FFToNameFavChatZZ:message sessionMsgList:sessionMsgList];
} else {
switch (WeChatTweak.revokedMessageStyle) {
case WTRevokedMessageStyleClassic:
[self handleRevokedMessageIntoClassicStyleWithSession:session messageData:messageData replaceMessage:replaceMessage];
break;
case WTRevokedMessageStyleMask:
[self handleRevokedMessageIntoMaskStyleWithSession:session messageData:messageData replaceMessage:replaceMessage];
break;
default:
break;
}
[self handleRevokedMessageIntoWithSession:session messageData:messageData replaceMessage:replaceMessage];
}
}
- (void)handleRevokedMessageIntoClassicStyleWithSession:(NSString *)session messageData:(MessageData *)messageData replaceMessage:(NSString *)replaceMessage {
// Prepare message data
MessageData *localMessageData = messageData;
MessageData *promptMessageData = ({
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;
data.msgContent = ({
NSString *fromUserName = [replaceMessage componentsSeparatedByString:@" "].firstObject;
NSString *userRevoke = [NSString stringWithFormat:@"%@ %@ ", fromUserName, [NSBundle.tweakBundle localizedStringForKey:@"Tweak.Message.Recalled"]];
NSString *tips = [NSString stringWithFormat:[NSBundle.tweakBundle localizedStringForKey:@"Tweak.Message.InterceptedARecalledMessage"], userRevoke];
NSMutableString *msgContent = [NSMutableString stringWithString:tips];
switch (localMessageData.messageType) {
case MessageDataTypeText: {
if (localMessageData.msgContent.length) {
if ([session rangeOfString:@"@chatroom"].location == NSNotFound) {
[msgContent appendFormat:@"\"%@\"", localMessageData.msgContent];
} else {
[msgContent appendFormat:@"\"%@\"", [localMessageData.msgContent componentsSeparatedByString:@":\n"].lastObject];
}
} else {
[msgContent appendString:[NSBundle.tweakBundle localizedStringForKey:@"Tweak.Message.AMessage"]];
}
break;
}
case MessageDataTypeImage:
[msgContent appendFormat:@"<%@>", [NSBundle.tweakBundle localizedStringForKey:@"Tweak.Message.Image"]]; break;
case MessageDataTypeVoice:
[msgContent appendFormat:@"<%@>", [NSBundle.tweakBundle localizedStringForKey:@"Tweak.Message.Voice"]]; break;
case MessageDataTypeVideo:
[msgContent appendFormat:@"<%@>", [NSBundle.tweakBundle localizedStringForKey:@"Tweak.Message.Video"]]; break;
case MessageDataTypeSticker:
[msgContent appendFormat:@"<%@>", [NSBundle.tweakBundle localizedStringForKey:@"Tweak.Message.Sticker"]]; break;
case MessageDataTypeAppUrl:
[msgContent appendFormat:@"<%@>", [NSBundle.tweakBundle localizedStringForKey:@"Tweak.Message.Link"]]; break;
default:
[msgContent appendString:[NSBundle.tweakBundle localizedStringForKey:@"Tweak.Message.AMessage"]]; break;
}
msgContent.copy;
});
data;
});
// Prepare notification information
MMServiceCenter *serviceCenter = [objc_getClass("MMServiceCenter") defaultCenter];
NSUserNotification *userNotification = [[NSUserNotification alloc] init];
BOOL isChatStatusNotifyOpen = YES;
if ([session rangeOfString:@"@chatroom"].location == NSNotFound) {
ContactStorage *contactStorage = [serviceCenter getService:objc_getClass("ContactStorage")];
WCContactData *contact = [contactStorage GetContact:session];
isChatStatusNotifyOpen = [contact isChatStatusNotifyOpen];
userNotification.informativeText = replaceMessage;
} else {
GroupStorage *groupStorage = [serviceCenter getService:objc_getClass("GroupStorage")];
WCContactData *groupContact = [groupStorage GetGroupContact:session];
isChatStatusNotifyOpen = [groupContact isChatStatusNotifyOpen];
NSString *groupName = groupContact.m_nsNickName.length ? groupContact.m_nsNickName : [NSBundle.tweakBundle localizedStringForKey:@"Tweak.Title.Group"];
userNotification.informativeText = [NSString stringWithFormat:@"%@: %@", groupName, replaceMessage];
}
// - (void)AddLocalMsg:(id)arg1 msgData:(id)arg2;
SEL addMsgSelector = NSSelectorFromString(@"AddLocalMsg:msgData:");
if ([self respondsToSelector:addMsgSelector]) {
((void (*)(id, SEL, id, id))objc_msgSend)(self, addMsgSelector, session, promptMessageData);
}
// Dispatch notification
dispatch_async(dispatch_get_main_queue(), ^{
// Deliver notification
RevokeNotificationType notificationType = [[NSUserDefaults standardUserDefaults] integerForKey:WeChatTweakPreferenceRevokeNotificationTypeKey];
if (notificationType == RevokeNotificationTypeReceiveAll || (notificationType == RevokeNotificationTypeFollow && isChatStatusNotifyOpen)) {
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:userNotification];
}
});
}
- (void)handleRevokedMessageIntoMaskStyleWithSession:(NSString *)session messageData:(MessageData *)messageData replaceMessage:(NSString *)replaceMessage {
- (void)handleRevokedMessageIntoWithSession:(NSString *)session messageData:(MessageData *)messageData replaceMessage:(NSString *)replaceMessage {
MMRevokeMsgService *service = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("MMRevokeMsgService")];
[service.db insertRevokeMsg:({
RevokeMsgItem *item = [[objc_getClass("RevokeMsgItem") alloc] init];
@@ -170,7 +84,7 @@ static void __attribute__((constructor)) tweak(void) {
dispatch_async(dispatch_get_main_queue(), ^{
// Deliver notification
RevokeNotificationType notificationType = [[NSUserDefaults standardUserDefaults] integerForKey:WeChatTweakPreferenceRevokeNotificationTypeKey];
if (notificationType == RevokeNotificationTypeReceiveAll || (notificationType == RevokeNotificationTypeFollow && isChatStatusNotifyOpen)) {
if (notificationType == RevokeNotificationTypeReceiveAll || (notificationType == RevokeNotificationTypeInherited && isChatStatusNotifyOpen)) {
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:userNotification];
}
});
@@ -187,7 +101,7 @@ static void __attribute__((constructor)) tweak(void) {
revokeTextField.usesSingleLineMode = YES;
revokeTextField.tag = 9527;
revokeTextField.stringValue = [NSBundle.tweakBundle localizedStringForKey:@"Tweak.Message.RecalledMark"];
revokeTextField.font = [NSFont systemFontOfSize:10];
revokeTextField.font = [NSFont systemFontOfSize:7.0];
revokeTextField.textColor = [NSColor lightGrayColor];
[revokeTextField sizeToFit];
[view addSubview:revokeTextField];
@@ -1,26 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="20037" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="20037"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="TweakPreferencesController">
<connections>
<outlet property="notificationTypeButton" destination="6x2-KV-p8w" id="Kfn-2a-Yup"/>
<outlet property="revokedMessageStyleButton" destination="eqS-1n-9dO" id="QVg-Sy-CoY"/>
<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="431" height="88"/>
<rect key="frame" x="0.0" y="0.0" width="431" height="56"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="B87-eD-uhI">
<rect key="frame" x="10" y="52" width="186" height="16"/>
<rect key="frame" x="10" y="20" width="186" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" refusesFirstResponder="YES" sendsActionOnEndEditing="YES" alignment="right" title="Message recalled notification:" usesSingleLineMode="YES" id="UKv-CM-nGt">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -28,7 +27,7 @@
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" horizontalCompressionResistancePriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="6x2-KV-p8w">
<rect key="frame" x="199" y="46" width="93" height="25"/>
<rect key="frame" x="199" y="14" width="93" height="25"/>
<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"/>
@@ -50,59 +49,15 @@
<action selector="switchNotificationTypeAction:" target="-2" id="xjO-Ck-wem"/>
</connections>
</popUpButton>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7wK-v5-BgQ">
<rect key="frame" x="46" y="20" width="150" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" refusesFirstResponder="YES" sendsActionOnEndEditing="YES" alignment="right" title="Revoked message style:" usesSingleLineMode="YES" id="mPT-nA-idf">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="eqS-1n-9dO">
<rect key="frame" x="199" y="14" width="83" height="25"/>
<popUpButtonCell key="cell" type="push" title="Classic" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="axesIndependently" inset="2" selectedItem="wRC-UO-k1G" id="6UY-90-fFH">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="FiI-39-AD8">
<items>
<menuItem title="Classic" state="on" id="wRC-UO-k1G">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Mask" id="gH0-wV-Bx0">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
</items>
</menu>
</popUpButtonCell>
<connections>
<action selector="switchRevokedMessageStyleButton:" target="-2" id="n3n-hX-s3H"/>
</connections>
</popUpButton>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ftV-1F-OnB">
<rect key="frame" x="286" y="20" width="130" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" refusesFirstResponder="YES" sendsActionOnEndEditing="YES" alignment="left" title="Experimental feature" usesSingleLineMode="YES" id="lHs-du-a6F">
<font key="font" metaFont="system"/>
<color key="textColor" name="systemRedColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="B87-eD-uhI" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="12" id="9tt-Vb-9e8"/>
<constraint firstItem="7wK-v5-BgQ" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="12" id="BjP-RS-ASM"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="ftV-1F-OnB" secondAttribute="trailing" constant="12" id="Bug-Cf-VNT"/>
<constraint firstItem="eqS-1n-9dO" firstAttribute="centerY" secondItem="7wK-v5-BgQ" secondAttribute="centerY" id="Pbm-17-TcF"/>
<constraint firstItem="7wK-v5-BgQ" firstAttribute="top" secondItem="B87-eD-uhI" secondAttribute="bottom" constant="16" id="Rqw-MY-e4X"/>
<constraint firstItem="B87-eD-uhI" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" id="acJ-lS-NeF"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="6x2-KV-p8w" secondAttribute="trailing" constant="12" id="e8z-dC-BAg"/>
<constraint firstItem="ftV-1F-OnB" firstAttribute="leading" secondItem="eqS-1n-9dO" secondAttribute="trailing" constant="10" id="g0f-zV-Ldd"/>
<constraint firstItem="eqS-1n-9dO" firstAttribute="leading" secondItem="7wK-v5-BgQ" secondAttribute="trailing" constant="8" symbolic="YES" id="ghN-pe-dKr"/>
<constraint firstItem="6x2-KV-p8w" firstAttribute="centerY" secondItem="B87-eD-uhI" secondAttribute="centerY" id="gqp-om-e0O"/>
<constraint firstItem="6x2-KV-p8w" firstAttribute="leading" secondItem="B87-eD-uhI" secondAttribute="trailing" constant="8" id="i7Z-7c-5cX"/>
<constraint firstItem="ftV-1F-OnB" firstAttribute="centerY" secondItem="eqS-1n-9dO" secondAttribute="centerY" id="v6d-17-iac"/>
<constraint firstItem="7wK-v5-BgQ" firstAttribute="trailing" secondItem="B87-eD-uhI" secondAttribute="trailing" id="ydo-VW-YRZ"/>
</constraints>
<point key="canvasLocation" x="138.5" y="162"/>
<point key="canvasLocation" x="138.5" y="146"/>
</customView>
</objects>
</document>
@@ -12,7 +12,6 @@
@interface TweakPreferencesController () <MASPreferencesViewController>
@property (weak) IBOutlet NSPopUpButton *notificationTypeButton;
@property (weak) IBOutlet NSPopUpButton *revokedMessageStyleButton;
@end
@@ -28,21 +27,13 @@
}
- (void)reloadData {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
RevokeNotificationType notificationType = [userDefaults integerForKey:WeChatTweakPreferenceRevokeNotificationTypeKey];
[self.notificationTypeButton selectItemAtIndex:notificationType];
[self.revokedMessageStyleButton selectItemAtIndex:WeChatTweak.revokedMessageStyle];
[self.notificationTypeButton selectItemAtIndex:[NSUserDefaults.standardUserDefaults integerForKey:WeChatTweakPreferenceRevokeNotificationTypeKey]];
}
#pragma mark - Event method
- (IBAction)switchNotificationTypeAction:(NSPopUpButton *)sender {
RevokeNotificationType type = sender.indexOfSelectedItem;
[[NSUserDefaults standardUserDefaults] setInteger:type forKey:WeChatTweakPreferenceRevokeNotificationTypeKey];
}
- (IBAction)switchRevokedMessageStyleButton:(NSPopUpButton *)sender {
WeChatTweak.revokedMessageStyle = sender.indexOfSelectedItem;
[NSUserDefaults.standardUserDefaults setInteger:sender.indexOfSelectedItem forKey:WeChatTweakPreferenceRevokeNotificationTypeKey];
}
#pragma mark - MASPreferencesViewController
@@ -8,17 +8,5 @@
/* Class = "NSMenuItem"; title = "All"; ObjectID = "da4-aJ-lEy"; */
"da4-aJ-lEy.title" = "All";
/* Class = "NSMenuItem"; title = "Mask"; ObjectID = "gH0-wV-Bx0"; */
"gH0-wV-Bx0.title" = "Mask";
/* Class = "NSMenuItem"; title = "Inherited"; ObjectID = "gec-CY-E1x"; */
"gec-CY-E1x.title" = "Inherited";
/* Class = "NSTextFieldCell"; title = "Experimental feature"; ObjectID = "lHs-du-a6F"; */
"lHs-du-a6F.title" = "Experimental feature";
/* Class = "NSTextFieldCell"; title = "Revoked message style:"; ObjectID = "mPT-nA-idf"; */
"mPT-nA-idf.title" = "Revoked message style:";
/* Class = "NSMenuItem"; title = "Classic"; ObjectID = "wRC-UO-k1G"; */
"wRC-UO-k1G.title" = "Classic";
@@ -8,17 +8,5 @@
/* Class = "NSMenuItem"; title = "All"; ObjectID = "da4-aJ-lEy"; */
"da4-aJ-lEy.title" = "全部接收";
/* Class = "NSMenuItem"; title = "Mask"; ObjectID = "gH0-wV-Bx0"; */
"gH0-wV-Bx0.title" = "遮罩";
/* Class = "NSMenuItem"; title = "Inherited"; ObjectID = "gec-CY-E1x"; */
"gec-CY-E1x.title" = "跟随聊天设置";
/* Class = "NSTextFieldCell"; title = "Experimental feature"; ObjectID = "lHs-du-a6F"; */
"lHs-du-a6F.title" = "试验性功能";
/* Class = "NSTextFieldCell"; title = "Revoked message style:"; ObjectID = "mPT-nA-idf"; */
"mPT-nA-idf.title" = "消息撤回样式:";
/* Class = "NSMenuItem"; title = "Classic"; ObjectID = "wRC-UO-k1G"; */
"wRC-UO-k1G.title" = "经典";
@@ -8,17 +8,5 @@
/* Class = "NSMenuItem"; title = "All"; ObjectID = "da4-aJ-lEy"; */
"da4-aJ-lEy.title" = "全部接收";
/* Class = "NSMenuItem"; title = "Mask"; ObjectID = "gH0-wV-Bx0"; */
"gH0-wV-Bx0.title" = "遮罩";
/* Class = "NSMenuItem"; title = "Inherited"; ObjectID = "gec-CY-E1x"; */
"gec-CY-E1x.title" = "跟隨聊天設置";
/* Class = "NSTextFieldCell"; title = "Experimental feature"; ObjectID = "lHs-du-a6F"; */
"lHs-du-a6F.title" = "試驗性功能";
/* Class = "NSTextFieldCell"; title = "Revoked message style:"; ObjectID = "mPT-nA-idf"; */
"mPT-nA-idf.title" = "消息撤回樣式:";
/* Class = "NSMenuItem"; title = "Classic"; ObjectID = "wRC-UO-k1G"; */
"wRC-UO-k1G.title" = "經典";
@@ -12,7 +12,7 @@
#import <JRSwizzle/JRSwizzle.h>
typedef NS_ENUM(NSUInteger, RevokeNotificationType) {
RevokeNotificationTypeFollow = 0,
RevokeNotificationTypeInherited = 0,
RevokeNotificationTypeReceiveAll,
RevokeNotificationTypeDisable,
};
-7
View File
@@ -11,13 +11,6 @@
FOUNDATION_EXPORT double WeChatTweakVersionNumber;
FOUNDATION_EXPORT const unsigned char WeChatTweakVersionString[];
typedef NS_ENUM(NSUInteger, WTRevokedMessageStyle) {
WTRevokedMessageStyleClassic = 0,
WTRevokedMessageStyleMask
};
@interface WeChatTweak : NSObject
@property (nonatomic, assign, class) WTRevokedMessageStyle revokedMessageStyle;
@end
-11
View File
@@ -8,17 +8,6 @@
#import "WeChatTweak.h"
static NSString * const WeChatTweakRevokedMessageStyleKey = @"WeChatTweakRevokedMessageStyleKey";
@implementation WeChatTweak
+ (WTRevokedMessageStyle)revokedMessageStyle {
return [NSUserDefaults.standardUserDefaults integerForKey:WeChatTweakRevokedMessageStyleKey];
}
+ (void)setRevokedMessageStyle:(WTRevokedMessageStyle)revokedMessageStyle {
[NSUserDefaults.standardUserDefaults setInteger:revokedMessageStyle forKey:WeChatTweakRevokedMessageStyleKey];
[NSUserDefaults.standardUserDefaults synchronize];
}
@end