欢迎大家前来讨论交流,我研究两天了,目前有所收获,可以实现自动抢红包,但是还有些不够完美。需要和大家交流.
我主要使用了cycript工具来观察程序的结构,找到感兴趣的几个类
通过class-dump出来头文件,找到对应的类
主要类有
BaseMsgContentViewController,这个可以对应到群
WCPayC2CMessageNodeView, 这个红包cell的contentview的subview
WCRedEnvelopesReceiveHomeView,这个是点击红包cell出来一个居中的框,上面还有个拆红包按钮
接受消息是BaseMsgContentViewController实现这个方法
- (void)MessageReturn:(unsigned int)arg1 MessageInfo:(NSDictionary *)arg2 Event:(unsigned int)arg3;
点击红包,会调用BaseMsgContentViewController的tapAppNodeView:方法
目前思路就是
%hook BaseMsgContentViewController
- (void)MessageReturn:(unsigned int)arg1 MessageInfo:(NSDictionary *)arg2 Event:(unsigned int)arg3
{
%orig;
UITableView *tableView = [self valueForKey:@"m_tableView"];
NSArray *cells = [tableView visibleCells];
for (UITableViewCell *cell in cells) {
for (UIView *view in cell.contentView.subviews) {
NSLog(@"+++++++++++++ %@", view);
if ([view isKindOfClass:%c(WCPayC2CMessageNodeView)]) {
NSLog(@"============== %@", view);
WCPayC2CMessageNodeView *v = (WCPayC2CMessageNodeView *)view;
[v performSelector:@selector(onClick)]; // 模拟点击的操作,会调用下面的tapAppNodeView:方法;
break;
}
}
}
}
- (void)tapAppNodeView:(WCPayC2CMessageNodeView *)arg1
{
// %c(CMessageNodeData);
// CMessageNodeData *node = [self findNodeDataByView:arg1];
// [node GetNodeViewType];
%orig;
}
%end
%hook WCRedEnvelopesReceiveHomeView
- (void)refreshViewWithData:(id)arg1
{
%orig;
[self performSelector:@selector(OnOpenRedEnvelopes)];
[self performSelector:@selector(OnCancelButtonDone)];
}
%end
我想说和我写的差不多。。。
请问怎么判断红包抢过没呀?
不用判断,我是取了一个巧,就是我只取最后一个cell看他是不是红包的cell,是的话调用onclick,如果抢了之后,微信下面会多一行cell显示你已经领取了红包,所以在进去最后一行的cell就不会是红包的cell,也就不会再执行那个onclick了
我突然发现我们的思路完全不同,不过我感觉我这个应该要好一点,给你看看代码
%hook BaseMsgContentViewController
%new
- (id)someValue {
return objc_getAssociatedObject(self, @selector(someValue));
}
%new
- (void)setSomeValue:(id)value {
objc_setAssociatedObject(self, @selector(someValue), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
%end
%hook BaseMsgContentViewController
- (id)tableView:(id)arg1 cellForRowAtIndexPath:(id)arg2
{
UITableViewCell *cell = %orig(arg1,arg2);
NSIndexPath *indexpath = arg2;
NSString *value = [self performSelector:@selector(someValue)];
if(indexpath.row + 1 == [value integerValue])
{
for (id subView in cell.contentView.subviews)
{
if([NSStringFromClass([subView class]) isEqualToString:@"WCPayC2CMessageNodeView"])
{
[subView performSelector:@selector(onClick)];
}
}
}
return cell;
}
- (long long)tableView:(id)arg1 numberOfRowsInSection:(long long)arg2
{
long long result = %orig(arg1,arg2);
[self performSelector:@selector(setSomeValue:) withObject:[NSString stringWithFormat:@"%zd",result]];
return result;
}
%end
%hook WCPayC2CMessageNodeView
%new
- (id)timer {
return objc_getAssociatedObject(self, @selector(timer));
}
%new
- (void)setTimer:(id)value {
objc_setAssociatedObject(self, @selector(timer), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
%end
%hook WCPayC2CMessageNodeView
- (void)onClick
{
%orig;
NSTimer *timeer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(find) userInfo:nil repeats:YES];
[self performSelector:@selector(setTimer:) withObject:timeer];
}
%end
%hook WCPayC2CMessageNodeView
%new
- (void)find
{
UIApplication *app = [UIApplication sharedApplication];
UIWindow *keyWindow = app.keyWindow;
for (id subView in keyWindow.subviews)
{
if([NSStringFromClass([subView class]) isEqualToString:@"WCRedEnvelopesReceiveHomeView"])
{
[subView performSelector:@selector(OnOpenRedEnvelopes)];
NSTimer *timer = [self performSelector:@selector(timer)];
[timer invalidate];
}
}
}
%end
非常感谢,我先研究研究
说下我的思路吧,有点奇葩,我是判断cell刷新的时候最后一个cell是不是红包cell如果是的话调用onclick方法,这个时候应该会请求网络来创建一个View,但是我无法判断这个view是什么时候出现,于是我就开了一个定时器一秒刷20次,来看这个view出现没,出现了就调用拆红包的方法,基本没问题,希望有更好的想法能交流下
可以直接hook那个view呀,就是这个WCRedEnvelopesReceiveHomeView
基本上hook这个方法就可以了
%hook WCRedEnvelopesReceiveHomeView
(void)refreshViewWithData:(id)arg1
{
%orig;
[self performSelector:@selector(OnOpenRedEnvelopes)];
[self performSelector:@selector(OnCancelButtonDone)];
}
%end
不错不错,当时没仔细看到这个方法
菜鸟问个问题,怎么知道有人发了红包呢?!以前看人说过是监听系统推送,然后判断是不是红包的,如果是就执行打开红包的操作,不知道楼主是怎么实现的。
暂时还不能根据消息判断是不是红包,只是根据cell的内容来判断的
你们都还停留在UI层;其实再往下一层,到逻辑层,就可以看到逻辑上微信接受到一条消息时的回调函数,如果在那个层面操作,就可以不用判断cell类型之类的东西,而专注在消息本身了。
(提示:如果遇到了CMessageMgr
这个类,就说明方向对了)
狗神66的~
刚研究,还请多多指导
大家目前讲的都是自动抢红包,有没有什么思路可以抢到最大或者略大一点的红包?
看看随机的算法是怎么实现的?
服务器决定的
狗神还有个小问题,收到红包消息包时,怎么拿到发送者的昵称,而不是微信号