279 lines
8.7 KiB
Objective-C
279 lines
8.7 KiB
Objective-C
//
|
|
// GiftComboManager.m
|
|
// YuMi
|
|
//
|
|
// Created by P on 2024/9/5.
|
|
//
|
|
// 处理连击面板逻辑
|
|
|
|
#import "GiftComboManager.h"
|
|
|
|
#import "UserInfoModel.h"
|
|
#import "AttachmentModel.h"
|
|
#import "GiftReceiveInfoModel.h"
|
|
#import "XPMessageRemoteExtModel.h"
|
|
|
|
#import "Api+Gift.h"
|
|
|
|
@interface GiftComboManager ()
|
|
|
|
// 用来存储 GiftReceiveInfoModel 和 NSDictionary 的元数据队列
|
|
@property (nonatomic, strong) NSMutableArray *giftComboQueue;
|
|
|
|
// 定时器,处理请求的调度器
|
|
@property (nonatomic, strong) dispatch_source_t timer;
|
|
|
|
@property (nonatomic, copy) NSArray *sendGiftToUIDs;
|
|
@property (nonatomic, assign) GiftSourceType giftSourceType;
|
|
@property (nonatomic, strong) GiftInfoModel *giftInfo;
|
|
@property (nonatomic, assign) RoomSendGiftType roomSendGiftType;
|
|
@property (nonatomic, copy) NSString *roomUID;
|
|
@property (nonatomic, copy) NSString *giftNumPerTimes;
|
|
@property (nonatomic, strong) UserInfoModel *sendGiftUserInfo;
|
|
@property (nonatomic, copy) NSString *sessionID;
|
|
|
|
@property (nonatomic, assign) NSInteger combo;
|
|
|
|
@end
|
|
|
|
@implementation GiftComboManager
|
|
|
|
#pragma mark - 单例方法
|
|
|
|
+ (instancetype)sharedManager {
|
|
static GiftComboManager *sharedInstance = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
sharedInstance = [[self alloc] init];
|
|
sharedInstance.giftComboQueue = [NSMutableArray array];
|
|
});
|
|
return sharedInstance;
|
|
}
|
|
|
|
// 添加 GiftReceiveInfoModel 和 metadata 到队列
|
|
- (void)addGiftComboWithInfo:(GiftReceiveInfoModel *)info andMetadata:(NSDictionary *)metadata {
|
|
if (info && metadata) {
|
|
// 将元数据打包成字典并添加到队列
|
|
@synchronized (self) {
|
|
NSDictionary *comboData = @{@"info": info, @"metadata": metadata};
|
|
[self.giftComboQueue addObject:comboData];
|
|
}
|
|
// 启动定时器
|
|
[self startProcessingQueue];
|
|
}
|
|
}
|
|
|
|
- (void)addComboFromNIMAttachment:(AttachmentModel *)attachment {
|
|
if (attachment) {
|
|
// 将元数据打包成字典并添加到队列
|
|
@synchronized (self) {
|
|
[self.giftComboQueue addObject:attachment];
|
|
}
|
|
// 启动定时器
|
|
[self startProcessingQueue];
|
|
}
|
|
}
|
|
|
|
// 开始连击,重置
|
|
- (void)resetCombo {
|
|
_combo = 1;
|
|
}
|
|
|
|
// MARK: Logic is 连击面板出现后,每点击一次,就触发一次面板最后的请求,请求成功后,构造云信消息体,消息体进入队列并按 0.2s 一次的频率发送消息
|
|
|
|
#pragma mark - 管理队列
|
|
|
|
// 开始处理队列
|
|
- (void)startProcessingQueue {
|
|
if (self.timer) {
|
|
return; // 如果定时器已经在运行,直接返回
|
|
}
|
|
|
|
// 创建 GCD 定时器
|
|
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
|
|
|
|
// 设置定时器时间间隔:每 0.2 秒执行一次
|
|
dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, 0.2 * NSEC_PER_SEC, 0.01 * NSEC_PER_SEC);
|
|
|
|
// 定时器触发的事件处理
|
|
dispatch_source_set_event_handler(self.timer, ^{
|
|
[self processGiftComboQueue];
|
|
});
|
|
|
|
// 启动定时器
|
|
dispatch_resume(self.timer);
|
|
}
|
|
|
|
// 停止处理队列
|
|
- (void)stopProcessingQueue {
|
|
if (self.timer) {
|
|
dispatch_source_cancel(self.timer);
|
|
self.timer = nil;
|
|
}
|
|
}
|
|
|
|
// 处理队列中的第一个请求
|
|
- (void)processGiftComboQueue {
|
|
@synchronized (self) {
|
|
if (self.giftComboQueue.count > 0) {
|
|
// 获取并移除队列中的第一个元数据
|
|
AttachmentModel *attachment = [self.giftComboQueue firstObject];
|
|
[self.giftComboQueue removeObjectAtIndex:0];
|
|
|
|
// 处理逻辑
|
|
[self processGiftComboWith:attachment];
|
|
} else {
|
|
// 如果队列为空,停止定时器
|
|
[self stopProcessingQueue];
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
NSLog(@"礼物处理完成");
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// 处理元数据的实际逻辑
|
|
- (void)processGiftComboWith:(AttachmentModel *)info {
|
|
[self sendCustomMessage:info];
|
|
}
|
|
|
|
#pragma mark - Gift meta data
|
|
- (void)saveSendGiftTo:(NSArray *)UIDs
|
|
{
|
|
_sendGiftToUIDs = UIDs;
|
|
}
|
|
|
|
- (void)saveGiftSourceType:(GiftSourceType)type
|
|
{
|
|
_giftSourceType = type;
|
|
}
|
|
|
|
- (void)saveSendGiftInfo:(GiftInfoModel *)model
|
|
{
|
|
_giftInfo = model;
|
|
}
|
|
|
|
- (void)saveSendGiftType:(RoomSendGiftType)type
|
|
{
|
|
_roomSendGiftType = type;
|
|
}
|
|
|
|
- (void)saveRoomUID:(NSString *)roomUID {
|
|
_roomUID = roomUID;
|
|
}
|
|
|
|
- (void)saveSendGiftNum:(NSString *)numString
|
|
{
|
|
_giftNumPerTimes = numString;
|
|
}
|
|
|
|
- (void)saveUserInfo:(UserInfoModel *)userInfo {
|
|
_sendGiftUserInfo = userInfo;
|
|
}
|
|
|
|
- (void)saveSessionID:(NSString *)sessionID {
|
|
_sessionID = sessionID;
|
|
}
|
|
|
|
#pragma mark - XPGiftPresenter
|
|
|
|
- (void)sendGift {
|
|
NSString *allUIDs = @"";
|
|
for (NSString *item in self.sendGiftToUIDs) {
|
|
if (allUIDs.length > 0) {
|
|
allUIDs = [allUIDs stringByAppendingString:@","];
|
|
}
|
|
allUIDs = [allUIDs stringByAppendingString:item];
|
|
}
|
|
@kWeakify(self);
|
|
[Api requestSendGift:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
|
|
@kStrongify(self);
|
|
if (code == 200) {
|
|
GiftReceiveInfoModel *receive = [GiftReceiveInfoModel modelWithJSON:data.data];
|
|
receive.sourceType = self.giftSourceType;
|
|
receive.roomSendGiftType = self.roomSendGiftType;
|
|
[self handleSendGiftSuccess:data];
|
|
} else {
|
|
// TODO: 发送失败处理
|
|
}
|
|
}
|
|
targetUids:allUIDs
|
|
giftNum:self.giftNumPerTimes
|
|
sendType:[NSString stringWithFormat:@"%ld", GiftSendType_OnMic]
|
|
giftId:[NSString stringWithFormat:@"%ld", self.giftInfo.giftId]
|
|
giftSource:[NSString stringWithFormat:@"%ld", self.giftSourceType]
|
|
giftType:[NSString stringWithFormat:@"%ld", self.giftInfo.giftType]
|
|
roomUid:self.roomUID
|
|
msg:@""
|
|
uid:[AccountInfoStorage instance].getUid];
|
|
}
|
|
|
|
- (void)handleSendGiftSuccess:(BaseModel *)response {
|
|
GiftReceiveInfoModel *receive = [GiftReceiveInfoModel modelWithJSON:response.data];
|
|
if (!receive) {
|
|
return;
|
|
}
|
|
|
|
NSDictionary *tempDic = response.data;
|
|
NSMutableDictionary *data = [NSMutableDictionary dictionary];
|
|
[data addEntriesFromDictionary:tempDic];
|
|
|
|
AttachmentModel *attachment = [[AttachmentModel alloc] init];
|
|
switch (receive.roomSendGiftType) {
|
|
case RoomSendGiftType_AllMic: {
|
|
attachment.first = CustomMessageType_AllMicroSend;
|
|
attachment.second = Custom_Message_Sub_AllMicroSend;
|
|
[data setObject:[tempDic valueForKeyPath:@"targetUsers.uid"] forKey:@"targetUids"];
|
|
attachment.data = data;
|
|
}
|
|
break;
|
|
case RoomSendGiftType_MutableOnMic: {
|
|
attachment.first = CustomMessageType_AllMicroSend;
|
|
attachment.second = Custom_Message_Sub_AllBatchSend;
|
|
attachment.data = data;
|
|
}
|
|
break;
|
|
case RoomSendGiftType_ToOne: {
|
|
attachment.first = CustomMessageType_Gift;
|
|
attachment.second = Custom_Message_Sub_Gift_Send;
|
|
NSDictionary *targetUsers = ((NSArray *)[data objectForKey:@"targetUsers"]).firstObject;
|
|
[data setObject:[targetUsers valueForKeyPath:@"uid"] forKey:@"targetUid"];
|
|
[data setObject:[targetUsers valueForKeyPath:@"nick"] forKey:@"targetNick"];
|
|
[data setObject:[targetUsers valueForKeyPath:@"avatar"] forKey:@"targetAvatar"];
|
|
attachment.data = data;
|
|
}
|
|
break;
|
|
default:
|
|
attachment = nil;
|
|
break;
|
|
}
|
|
|
|
if (attachment) {
|
|
|
|
// TODO: 添加到队列
|
|
[self sendCustomMessage:attachment];
|
|
}
|
|
}
|
|
|
|
- (void)sendCustomMessage:(AttachmentModel *)attachment {
|
|
NIMMessage *message = [[NIMMessage alloc]init];
|
|
NIMCustomObject *object = [[NIMCustomObject alloc] init];
|
|
object.attachment = attachment;
|
|
message.messageObject = object;
|
|
|
|
UserInfoModel *userInfo = self.sendGiftUserInfo;
|
|
XPMessageRemoteExtModel *extModel = [[XPMessageRemoteExtModel alloc] init];
|
|
extModel.androidBubbleUrl = userInfo.androidBubbleUrl;
|
|
extModel.iosBubbleUrl = userInfo.iosBubbleUrl;
|
|
extModel.fromSayHelloChannel = userInfo.fromSayHelloChannel;
|
|
NSMutableDictionary *remoteExt = [NSMutableDictionary dictionaryWithObject:extModel.model2dictionary forKey:[NSString stringWithFormat:@"%ld", userInfo.uid]];
|
|
message.remoteExt = remoteExt;
|
|
|
|
//构造会话
|
|
NIMSession *session = [NIMSession session:self.sessionID type:NIMSessionTypeChatroom];
|
|
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil];
|
|
}
|
|
|
|
|
|
@end
|