更新房间功能,新增 MicCpInfoModel 类以管理麦位关系数据,优化房间中点矩形和麦位状态管理逻辑。同时,更新相关 Presenter 和 ViewController 以集成新的麦位关系 API,提升代码可维护性和用户体验。新增麦位状态监测和更新机制,确保用户在房间中的麦位信息实时准确。
This commit is contained in:
@@ -94,6 +94,10 @@
|
||||
#import "RoomResourceManager.h"
|
||||
#import "LuckyPackageLogicManager.h"
|
||||
|
||||
#import "MicCpInfoModel.h"
|
||||
#import "XPMessageRemoteExtModel.h"
|
||||
#import "MicMidpointRectManager.h"
|
||||
|
||||
// 🔧 新增:Turbo Mode Tips 相关
|
||||
#import "XPTurboModeTipsManager.h"
|
||||
#import "BuglyManager.h"
|
||||
@@ -194,6 +198,10 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
///是否正在显示红包弹窗,防止显示多个弹窗
|
||||
@property(nonatomic,assign) BOOL isShowRedPacket;
|
||||
@property(nonatomic,copy) NSString *releaseCoins;
|
||||
|
||||
// 🔧 防护机制:房间状态标志位
|
||||
@property (atomic, assign) BOOL isExitingRoom; // 是否正在退出房间
|
||||
@property (atomic, assign) BOOL isViewActive; // VC 是否可见/活跃
|
||||
@property(nonatomic,copy) NSString *myCoins;
|
||||
|
||||
@property(nonatomic,strong) UIButton *exitGameButton;
|
||||
@@ -204,6 +212,13 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
/// 🔧 修复:保存 block 形式的通知观察者,防止内存泄漏
|
||||
@property(nonatomic,strong) id<NSObject> exchangeRoomAnimationViewObserver;
|
||||
|
||||
/// 当前房间的CP关系列表(用于在中点关系位播放对应cp等级的SVGA)
|
||||
@property (nonatomic, strong) NSArray<MicCpInfoModel *> *currentCpList;
|
||||
@property (nonatomic, assign) BOOL currentUserMicStatusChanged; // 当前用户麦位状态是否发生变化(上麦、下麦、换位)
|
||||
@property (nonatomic, assign) BOOL currentUserWasOnMic; // 当前用户之前是否在麦上
|
||||
@property (nonatomic, assign) NSInteger currentUserMicPosition; // 当前用户的麦位位置(-1表示不在麦上)
|
||||
@property (nonatomic, assign) BOOL hasCompletedRoomInitialization; // 是否已完成进房初始化
|
||||
|
||||
@end
|
||||
|
||||
@implementation XPRoomViewController
|
||||
@@ -296,6 +311,13 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
|
||||
NSLog(@"🔄 XPRoomViewController: 开始销毁");
|
||||
|
||||
// 🔧 防护:强制清理 TRTC 连接,防止资源泄漏
|
||||
[[RtcManager instance] exitRoom];
|
||||
|
||||
// 🔧 防护:标记房间正在退出,防止后续异步回调
|
||||
self.isExitingRoom = YES;
|
||||
self.isViewActive = NO;
|
||||
|
||||
[[RoomBoomManager sharedManager] leaveRoom];
|
||||
|
||||
[XPSkillCardPlayerManager shareInstance].photoIdList = nil;
|
||||
@@ -552,6 +574,15 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
[super viewWillDisappear:animated];
|
||||
self.freeView.hidden = YES;
|
||||
|
||||
// 🔧 防护:标记 VC 即将不可见
|
||||
self.isViewActive = NO;
|
||||
|
||||
// 🔧 防护:如果 VC 被移除或 dismiss,强制清理 TRTC
|
||||
if (self.isMovingFromParentViewController || self.isBeingDismissed) {
|
||||
[[RtcManager instance] exitRoom];
|
||||
self.isExitingRoom = YES;
|
||||
}
|
||||
|
||||
// 如果连击正在进行,强制重置
|
||||
if ([[GiftComboManager sharedManager] isActive]) {
|
||||
NSLog(@"📱 房间即将退出,检查连击状态");
|
||||
@@ -564,6 +595,9 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
|
||||
[XPSkillCardPlayerManager shareInstance].isInRoomVC = NO;
|
||||
|
||||
// 🔧 防护:确保标记为不可见
|
||||
self.isViewActive = NO;
|
||||
|
||||
// 🔧 修复:发送房间退出通知,让 BuglyManager 知道用户已退出房间
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"RoomDidExit"
|
||||
object:nil
|
||||
@@ -576,6 +610,9 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
|
||||
[XPSkillCardPlayerManager shareInstance].isInRoomVC = YES;
|
||||
|
||||
// 🔧 防护:标记 VC 可见
|
||||
self.isViewActive = YES;
|
||||
|
||||
// 🔧 修复:发送房间进入通知,让 BuglyManager 知道用户已进入房间
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"RoomDidEnter"
|
||||
object:nil
|
||||
@@ -634,7 +671,9 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
[self.view addSubview:self.animationView];
|
||||
|
||||
// 🔧 新增:添加测试按钮,用于测试 Turbo Mode Tips 弹窗
|
||||
#if DEBUG
|
||||
[self addTestButton];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)__layoutTwentyMicStage {
|
||||
@@ -1029,6 +1068,13 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
|
||||
// 🔧 新增:如果是 SocialStageView,绘制中点矩形
|
||||
[self drawSocialStageMidpointRects];
|
||||
|
||||
// 🔧 新增:进房成功后调用CP相关API
|
||||
[self callMicCpListByRoomUidAfterRoomEntered];
|
||||
|
||||
// 🔧 新增:stage view类型变化时调用CP相关API
|
||||
NSMutableDictionary<NSString *,MicroQueueModel *> *currentQueue = [self.stageView getMicroQueue];
|
||||
[self callMicCpListByUidListOnMicChangeWithQueue:currentQueue];
|
||||
|
||||
[self addExitGameButton];
|
||||
|
||||
@@ -1362,7 +1408,10 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
[self.backContainerView onRoomEntered];
|
||||
[self.littleGameView onRoomEntered];
|
||||
if ([XPRoomMiniManager shareManager].getRoomInfo.uid != self.roomUid.integerValue) {// 最小化进房 还是原来的房间的话 不需要重新进入云信 因为压根没退
|
||||
[self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo];
|
||||
// 🔧 防护:检查是否允许进房
|
||||
if (!self.isExitingRoom && self.isViewActive) {
|
||||
[self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo];
|
||||
}
|
||||
[self.functionView onRoomEntered];
|
||||
[self.messageContainerView onRoomEntered];
|
||||
[self.menuContainerView onRoomEntered];
|
||||
@@ -1437,7 +1486,10 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
[self.backContainerView onRoomEntered];
|
||||
[self.littleGameView onRoomEntered];
|
||||
if ([XPRoomMiniManager shareManager].getRoomInfo.uid != self.roomUid.integerValue) {// 最小化进房 还是原来的房间的话 不需要重新进入云信 因为压根没退
|
||||
[self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo];
|
||||
// 🔧 防护:检查是否允许进房
|
||||
if (!self.isExitingRoom && self.isViewActive) {
|
||||
[self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo];
|
||||
}
|
||||
[self.functionView onRoomEntered];
|
||||
[self.messageContainerView onRoomEntered];
|
||||
[self.menuContainerView onRoomEntered];
|
||||
@@ -1661,15 +1713,27 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
|
||||
self.quickMessageContainerView.titleArray = self.roomInfo.speakTemplate;
|
||||
|
||||
[self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo];
|
||||
// 🔧 防护:检查是否允许进房
|
||||
if (!self.isExitingRoom && self.isViewActive) {
|
||||
[self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)enterRoomSuccess:(NIMChatroom *)chatRoom {
|
||||
[XNDJTDDLoadingTool hideHUDInView:self.navigationController.view];
|
||||
|
||||
// 🔧 防护:检查 VC 是否仍然有效
|
||||
if (self.isExitingRoom || !self.isViewActive) {
|
||||
NSLog(@"🔧 enterRoomSuccess: VC 已退出或不可见,忽略回调");
|
||||
return;
|
||||
}
|
||||
|
||||
[self.stageView onRoomEntered];
|
||||
[self.functionView onRoomEntered];
|
||||
|
||||
// 🔧 新增:初始化当前用户的麦位状态
|
||||
[self initializeCurrentUserMicStatus];
|
||||
|
||||
//上报进房
|
||||
if (self.roomInfo != nil) {
|
||||
[self.presenter reportUserInterRoom:[NSString stringWithFormat:@"%zd", self.roomInfo.uid]];
|
||||
@@ -1685,6 +1749,13 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
- (void)enterRoomFail:(NSInteger)code {
|
||||
[XNDJTDDLoadingTool hideHUDInView:self.navigationController.view];
|
||||
[self hideHUD];
|
||||
|
||||
// 🔧 防护:检查 VC 是否仍然有效
|
||||
if (self.isExitingRoom || !self.isViewActive) {
|
||||
NSLog(@"🔧 enterRoomFail: VC 已退出或不可见,忽略回调 (code: %ld)", (long)code);
|
||||
return;
|
||||
}
|
||||
|
||||
if (code == 13003) {
|
||||
[self showErrorToast:YMLocalizedString(@"XPRoomViewController3")];
|
||||
}
|
||||
@@ -1851,7 +1922,10 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
[self.backContainerView onRoomEntered];
|
||||
[self.littleGameView onRoomEntered];
|
||||
if ([XPRoomMiniManager shareManager].getRoomInfo.uid != self.roomUid.integerValue) {// 最小化进房 还是原来的房间的话 不需要重新进入云信 因为压根没退
|
||||
[self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo];
|
||||
// 🔧 防护:检查是否允许进房
|
||||
if (!self.isExitingRoom && self.isViewActive) {
|
||||
[self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo];
|
||||
}
|
||||
[self.functionView onRoomEntered];
|
||||
[self.messageContainerView onRoomEntered];
|
||||
[self.menuContainerView onRoomEntered];
|
||||
@@ -1882,7 +1956,6 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
[self.presenter openRoom:title type:type roomPwd:@"" roomDesc:@"" backPic:@"" mgId:self.mgId];
|
||||
}
|
||||
} else { // 当前用户进入别人房间
|
||||
// TODO: 房主已经下线。
|
||||
[self showSuccessToast:YMLocalizedString(@"XPRoomViewController7")];
|
||||
[self enterRoomFail:0];
|
||||
}
|
||||
@@ -1994,21 +2067,9 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
}
|
||||
|
||||
if (![message.session.sessionId isEqualToString:@(self.roomInfo.roomId).stringValue]) {
|
||||
// if (message.messageType == NIMMessageTypeCustom) {
|
||||
// NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
|
||||
// if ([obj.attachment isKindOfClass:[AttachmentModel class]]) {
|
||||
// AttachmentModel *att = (AttachmentModel *)obj.attachment;
|
||||
// if (!att.isFromPublic) {
|
||||
// NSLog(@"[Recv] ⛔️ 过滤:房间不匹配 | msg.sid=%@ | curRoomId=%@",
|
||||
// message.session.sessionId, @(self.roomInfo.roomId).stringValue);
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
// }else {
|
||||
NSLog(@"[Recv] ⛔️ 过滤:房间不匹配 | msg.sid=%@ | curRoomId=%@",
|
||||
message.session.sessionId, @(self.roomInfo.roomId).stringValue);
|
||||
continue;
|
||||
// }
|
||||
NSLog(@"[Recv] ⛔️ 过滤:房间不匹配 | msg.sid=%@ | curRoomId=%@",
|
||||
message.session.sessionId, @(self.roomInfo.roomId).stringValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
NSLog(@"[Recv] --- Message Raw Attach Content: %@, %@, %ld", @(message.senderClientType), message.rawAttachContent, (long)message.messageType);
|
||||
@@ -2021,20 +2082,6 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
if (message.messageType == NIMMessageTypeNotification) {
|
||||
[self handleNIMNotificationTypeMessage:message];
|
||||
} else if (message.messageType == NIMMessageTypeCustom) {
|
||||
// 自定义消息排查日志:first/second/size3
|
||||
#if DEBUG
|
||||
if ([message.messageObject isKindOfClass:[NIMCustomObject class]]) {
|
||||
NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
|
||||
if ([obj.attachment isKindOfClass:[AttachmentModel class]]) {
|
||||
AttachmentModel *att = (AttachmentModel *)obj.attachment;
|
||||
NSData *payloadJSON = nil;
|
||||
@try { payloadJSON = [NSJSONSerialization dataWithJSONObject:att.data ?: @{} options:0 error:nil]; } @catch (__unused NSException *e) {}
|
||||
NSLog(@"[Recv] 🎯 自定义消息 | first=%ld second=%ld | payload=%lub | sid=%@ | ts=%.3f",
|
||||
(long)att.first, (long)att.second, (unsigned long)payloadJSON.length,
|
||||
message.session.sessionId, [[NSDate date] timeIntervalSince1970]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
[self handleNimCustomTypeMessage:message];
|
||||
} else if(message.messageType == NIMMessageTypeText) {
|
||||
[self.messageContainerView handleNIMTextMessage:message];
|
||||
@@ -2158,7 +2205,6 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
//房间类型是否变更了(从个播->普通,个播->小游戏等)
|
||||
newRoomInfo.hadChangeRoomType = self.roomInfo.type != newRoomInfo.type;
|
||||
BOOL anchorToOther = newRoomInfo.type != RoomType_Anchor && self.roomInfo.type == RoomType_Anchor;//个播变其他房
|
||||
RoomType currentType = self.roomInfo.type;
|
||||
self.roomInfo = newRoomInfo;
|
||||
|
||||
[self.backContainerView onRoomUpdate];
|
||||
@@ -2424,10 +2470,78 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MicRelationship_Type:
|
||||
switch (attachment.second) {
|
||||
case MicRelationship_CP:
|
||||
[self handleMicRelationshipCPMessage:attachment];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 处理麦位关系CP消息
|
||||
- (void)handleMicRelationshipCPMessage:(AttachmentModel *)attachment {
|
||||
NSLog(@"🔧 接收到麦位关系CP消息");
|
||||
|
||||
if (!attachment.data || ![attachment.data isKindOfClass:[NSString class]]) {
|
||||
NSLog(@"⚠️ 麦位关系CP消息:data格式错误,跳过处理");
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *jsonString = (NSString *)attachment.data;
|
||||
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
NSError *error = nil;
|
||||
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"❌ 麦位关系CP消息:JSON解析失败 - %@", error.localizedDescription);
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证消息格式
|
||||
NSNumber *first = jsonDict[@"first"];
|
||||
NSNumber *second = jsonDict[@"second"];
|
||||
NSArray *dataArray = jsonDict[@"data"];
|
||||
|
||||
if (!first || !second || ![dataArray isKindOfClass:[NSArray class]]) {
|
||||
NSLog(@"⚠️ 麦位关系CP消息:消息格式错误,跳过处理");
|
||||
return;
|
||||
}
|
||||
|
||||
if (first.integerValue != MicRelationship_Type || second.integerValue != MicRelationship_CP) {
|
||||
NSLog(@"⚠️ 麦位关系CP消息:消息类型不匹配,跳过处理");
|
||||
return;
|
||||
}
|
||||
|
||||
// 解析CP数据
|
||||
NSMutableArray<MicCpInfoModel *> *cpList = [NSMutableArray array];
|
||||
for (NSDictionary *cpDict in dataArray) {
|
||||
if ([cpDict isKindOfClass:[NSDictionary class]]) {
|
||||
MicCpInfoModel *cpInfo = [[MicCpInfoModel alloc] init];
|
||||
cpInfo.uid = [cpDict[@"uid"] integerValue];
|
||||
cpInfo.loverUid = [cpDict[@"loverUid"] integerValue];
|
||||
cpInfo.cpLevel = [cpDict[@"cpLevel"] integerValue];
|
||||
[cpList addObject:cpInfo];
|
||||
}
|
||||
}
|
||||
|
||||
NSLog(@"🔧 麦位关系CP消息:解析到 %lu 条CP数据", (unsigned long)cpList.count);
|
||||
|
||||
// 更新当前CP列表
|
||||
self.currentCpList = cpList.copy;
|
||||
|
||||
// 更新 MicMidpointRectManager 的缓存
|
||||
[self updateMicMidpointRectManagerCache:cpList];
|
||||
|
||||
// 刷新CP SVGA显示
|
||||
[self drawSocialStageMidpointRects];
|
||||
|
||||
NSLog(@"🔧 麦位关系CP消息处理完成");
|
||||
}
|
||||
|
||||
- (void)handleUpMicAsk:(AttachmentModel *)attachment {
|
||||
NSNumber *targetUid = [attachment.data objectForKey:@"targetUid"];
|
||||
if (!targetUid || ![targetUid.stringValue isEqualToString:[AccountInfoStorage instance].getUid]) {
|
||||
@@ -2731,6 +2845,9 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
- (void)exitRoom {
|
||||
[XNDJTDDLoadingTool showLoading];
|
||||
|
||||
// 🔧 防护:标记正在退出房间
|
||||
self.isExitingRoom = YES;
|
||||
|
||||
[XPSkillCardPlayerManager shareInstance].micState = MICState_None;
|
||||
|
||||
[self.stageView exitNIMRoom];
|
||||
@@ -2849,7 +2966,14 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
[self.littleGameView destroyMG];
|
||||
}
|
||||
[[XPRoomMiniManager shareManager] resetLocalMessage];
|
||||
|
||||
// 🔧 防护:确保 TRTC 退出
|
||||
[[RtcManager instance] exitRoom];
|
||||
|
||||
// 🔧 防护:标记房间已退出
|
||||
self.isExitingRoom = YES;
|
||||
self.isViewActive = NO;
|
||||
|
||||
[self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]];
|
||||
[self.presenter reportUserOutRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.uid]];
|
||||
[self handleFirstOutRoom];
|
||||
@@ -2946,19 +3070,31 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
[self.functionView onRoomUpdate];
|
||||
[self.functionView onMicroQueueUpdate:queue];
|
||||
|
||||
BOOL isOnMic = false;
|
||||
for (MicroQueueModel * info in queue.allValues) {
|
||||
if (info.userInfo.uid > 0 && [AccountInfoStorage instance].getUid.integerValue == info.userInfo.uid) {
|
||||
isOnMic = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 更新当前用户的麦位状态
|
||||
[self updateCurrentUserMicStatus:queue];
|
||||
|
||||
// 获取当前用户麦位状态
|
||||
NSDictionary *currentStatus = [self getCurrentUserMicStatus:queue];
|
||||
BOOL isOnMic = [currentStatus[@"isOnMic"] boolValue];
|
||||
|
||||
if (isOnMic) {
|
||||
self.anchorScrollView.scrollEnabled = NO;
|
||||
} else {
|
||||
self.anchorScrollView.scrollEnabled = YES;
|
||||
}
|
||||
|
||||
// 🔧 新增:只有在完成进房初始化后才调用mic位变动API
|
||||
if (self.hasCompletedRoomInitialization) {
|
||||
// 检测下麦用户并处理CP关系缓存
|
||||
[self handleDownMicEventIfNeeded:queue];
|
||||
|
||||
// 🔧 :更新麦位快照
|
||||
[self updateMicMidpointRectManagerSnapshot];
|
||||
|
||||
[self callMicCpListByUidListOnMicChangeWithQueue:queue];
|
||||
} else {
|
||||
NSLog(@"🔧 进房初始化中,跳过 micCpListByUidList 调用");
|
||||
}
|
||||
}
|
||||
|
||||
- (CGPoint)animationPointAtStageViewByUid:(NSString *)uid {
|
||||
@@ -2978,6 +3114,28 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
[[RoomBoomManager sharedManager] receiveEnterRoomBoom:model];
|
||||
}
|
||||
|
||||
- (void)getMicCpListByRoomUidSuccess:(NSArray <MicCpInfoModel *> *)cpList {
|
||||
self.currentCpList = cpList;
|
||||
// 刷新绘制,按CP关系播放对应SVGA
|
||||
[self drawSocialStageMidpointRects];
|
||||
}
|
||||
|
||||
- (void)getMicCpListByUidListSuccess:(NSArray<MicCpInfoModel *> *)cpList {
|
||||
self.currentCpList = cpList;
|
||||
|
||||
// 🔧 :更新 MicMidpointRectManager 的缓存
|
||||
[self updateMicMidpointRectManagerCache:cpList];
|
||||
|
||||
// 刷新绘制,按CP关系播放对应SVGA
|
||||
[self drawSocialStageMidpointRects];
|
||||
|
||||
// 如果当前用户麦位状态发生变化(上麦、下麦、换位),发送 NIM message
|
||||
if (self.currentUserMicStatusChanged) {
|
||||
[self sendMicRelationshipNIMessage:cpList];
|
||||
self.currentUserMicStatusChanged = NO; // 重置标志
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - 首次退出非自己的房间,处理是否需要弹新用户充值优惠
|
||||
- (void)handleFirstOutRoom {
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
@@ -3056,7 +3214,10 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
[self.littleGameView onRoomEntered];
|
||||
[self.littleGameView onRoomEntered];
|
||||
if ([XPRoomMiniManager shareManager].getRoomInfo.uid != self.roomUid.integerValue) {// 最小化进房 还是原来的房间的话 不需要重新进入云信 因为压根没退
|
||||
[self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo];
|
||||
// 🔧 防护:检查是否允许进房
|
||||
if (!self.isExitingRoom && self.isViewActive) {
|
||||
[self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo];
|
||||
}
|
||||
[self.functionView onRoomEntered];
|
||||
[self.messageContainerView onRoomEntered];
|
||||
[self.menuContainerView onRoomEntered];
|
||||
@@ -3080,7 +3241,10 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
[self.backContainerView onRoomEntered];
|
||||
[self.littleGameView onRoomEntered];
|
||||
[self.functionView onRoomEntered];
|
||||
[self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo];
|
||||
// 🔧 防护:检查是否允许进房
|
||||
if (!self.isExitingRoom && self.isViewActive) {
|
||||
[self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo];
|
||||
}
|
||||
[self.messageContainerView onRoomEntered];
|
||||
[self.littleGameView onRoomEntered];
|
||||
[[XPRoomMiniManager shareManager] configRoomInfo:nil];
|
||||
@@ -3320,13 +3484,6 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用现有的消息处理流程
|
||||
// [self.messageContainerView handleNIMCustomMessage:message];
|
||||
// [self.animationView handleNIMCustomMessage:message];
|
||||
// [self handleNimCustomTypeMessage:message];
|
||||
// [self onRecvMessages:@[message]];
|
||||
|
||||
|
||||
switch (message.messageType) {
|
||||
case NIMMessageTypeNotification:
|
||||
[self handleNIMNotificationTypeMessage:message];
|
||||
@@ -3416,7 +3573,7 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
NSLog(@"🎮 卡顿检测模拟已触发,计数将增加");
|
||||
}
|
||||
|
||||
/// 调试方法:在所有 StageView 上绘制符合条件的相邻麦位中点矩形
|
||||
/// 在 StageView 上绘制符合条件的相邻麦位中点矩形
|
||||
- (void)drawSocialStageMidpointRects {
|
||||
if (!self.stageView) {
|
||||
NSLog(@"🔧 当前没有 stageView,跳过中点矩形绘制");
|
||||
@@ -3485,13 +3642,13 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
|
||||
CGRect rect = [self.stageView rectForMidpointBetweenMicAtIndex:firstIndex andIndex:secondIndex];
|
||||
if (!CGRectIsEmpty(rect)) {
|
||||
UIView *debugView = [[UIView alloc] initWithFrame:rect];
|
||||
debugView.backgroundColor = [[UIColor blueColor] colorWithAlphaComponent:0.3];
|
||||
debugView.layer.borderColor = [UIColor blueColor].CGColor;
|
||||
debugView.layer.borderWidth = 2.0;
|
||||
debugView.layer.cornerRadius = 8.0;
|
||||
debugView.tag = 56002;
|
||||
debugView.userInteractionEnabled = NO;
|
||||
UIView *micRelationshipView = [[UIView alloc] initWithFrame:rect];
|
||||
micRelationshipView.backgroundColor = [[UIColor blueColor] colorWithAlphaComponent:0.3];
|
||||
micRelationshipView.layer.borderColor = [UIColor blueColor].CGColor;
|
||||
micRelationshipView.layer.borderWidth = 2.0;
|
||||
micRelationshipView.layer.cornerRadius = 8.0;
|
||||
micRelationshipView.tag = 56002;
|
||||
micRelationshipView.userInteractionEnabled = NO;
|
||||
|
||||
// 添加标签显示麦位对
|
||||
UILabel *label = [[UILabel alloc] init];
|
||||
@@ -3499,23 +3656,22 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
label.textColor = [UIColor whiteColor];
|
||||
label.font = [UIFont boldSystemFontOfSize:12];
|
||||
label.textAlignment = NSTextAlignmentCenter;
|
||||
label.frame = debugView.bounds;
|
||||
[debugView addSubview:label];
|
||||
label.frame = micRelationshipView.bounds;
|
||||
[micRelationshipView addSubview:label];
|
||||
|
||||
// 根据不同的 StageView 类型添加到相应的容器
|
||||
if ([self.stageView isKindOfClass:[LittleGameScrollStageView class]]) {
|
||||
[(LittleGameScrollStageView *)self.stageView addMidpointRect:debugView];
|
||||
} else if ([self.stageView isKindOfClass:[LittleGameStageView class]]) {
|
||||
[(LittleGameStageView *)self.stageView addMidpointRect:debugView];
|
||||
} else if ([self.stageView respondsToSelector:@selector(midpointRectManager)]) {
|
||||
// 使用新的管理器添加中点矩形
|
||||
// 统一逻辑:优先通过 midpointRectManager 管理器添加与播放SVGA;无管理器时回退为直接添加
|
||||
if ([self.stageView respondsToSelector:@selector(midpointRectManager)]) {
|
||||
id manager = [self.stageView valueForKey:@"midpointRectManager"];
|
||||
if ([manager respondsToSelector:@selector(addMidpointRectAtFrame:micPairText:autoPlaySVGA:)]) {
|
||||
if ([manager respondsToSelector:@selector(addRelationshipAtFrame:micPairText:leftUid:rightUid:cpList:)]) {
|
||||
NSString *micPairText = [NSString stringWithFormat:@"%ld-%ld", (long)firstIndex, (long)secondIndex];
|
||||
[manager addMidpointRectAtFrame:rect micPairText:micPairText autoPlaySVGA:YES];
|
||||
UIView<MicroViewProtocol> *leftView = [self.stageView findMicroViewByIndex:firstIndex];
|
||||
UIView<MicroViewProtocol> *rightView = [self.stageView findMicroViewByIndex:secondIndex];
|
||||
NSInteger leftUid = [[leftView getUser] uid];
|
||||
NSInteger rightUid = [[rightView getUser] uid];
|
||||
[manager addRelationshipAtFrame:rect micPairText:micPairText leftUid:leftUid rightUid:rightUid cpList:self.currentCpList ?: @[]];
|
||||
}
|
||||
} else {
|
||||
[self.stageView addSubview:debugView];
|
||||
[self.stageView addSubview:micRelationshipView];
|
||||
}
|
||||
NSLog(@"🔧 绘制中点矩形: %ld-%ld, rect: %@", (long)firstIndex, (long)secondIndex, NSStringFromCGRect(rect));
|
||||
} else {
|
||||
@@ -3526,4 +3682,387 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
NSLog(@"🔧 %@ 中点矩形绘制完成", stageViewClass);
|
||||
}
|
||||
|
||||
/// 进房成功后调用CP相关API
|
||||
- (void)callMicCpListByRoomUidAfterRoomEntered {
|
||||
NSLog(@"🔧 进房成功:开始调用 micCpListByRoomUid API");
|
||||
|
||||
if (!self.roomInfo) {
|
||||
NSLog(@"⚠️ 进房成功:roomInfo为空,跳过CP API调用");
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *roomUid = [NSString stringWithFormat:@"%ld", (long)self.roomInfo.uid];
|
||||
NSLog(@"🔧 进房成功:房间UID: %@, 房间类型: %ld", roomUid, (long)self.roomInfo.type);
|
||||
|
||||
// 调用 micCpListByRoomUid 方法
|
||||
if ([self.presenter respondsToSelector:@selector(micCpListByRoomUid:)]) {
|
||||
NSLog(@"🔧 进房成功:调用 micCpListByRoomUid: %@", roomUid);
|
||||
[self.presenter micCpListByRoomUid:roomUid];
|
||||
} else {
|
||||
NSLog(@"⚠️ 进房成功:presenter不支持micCpListByRoomUid方法");
|
||||
}
|
||||
|
||||
NSLog(@"🔧 进房成功:micCpListByRoomUid API调用完成");
|
||||
}
|
||||
|
||||
/// 获取当前用户及其左右相邻用户的uid列表(最多3个)
|
||||
- (NSArray<NSString *> *)getAllMicUserUidsWithQueue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
|
||||
NSMutableArray<NSString *> *micUserUids = [NSMutableArray array];
|
||||
|
||||
if (!self.roomInfo) {
|
||||
NSLog(@"⚠️ 获取mic用户列表:roomInfo为空");
|
||||
return micUserUids;
|
||||
}
|
||||
|
||||
// 获取当前用户的麦位位置
|
||||
NSInteger currentUserMicPosition = self.currentUserMicPosition;
|
||||
if (currentUserMicPosition == -1) {
|
||||
NSLog(@"🔧 获取mic用户列表:当前用户不在麦上,返回空数据");
|
||||
return micUserUids;
|
||||
}
|
||||
|
||||
// 获取最大麦位数
|
||||
NSInteger maxMicCount = 0;
|
||||
switch (self.roomInfo.type) {
|
||||
case RoomType_Game:
|
||||
maxMicCount = 9;
|
||||
break;
|
||||
case RoomType_10Mic:
|
||||
maxMicCount = 10;
|
||||
break;
|
||||
case RoomType_15Mic:
|
||||
maxMicCount = 15;
|
||||
break;
|
||||
case RoomType_19Mic:
|
||||
maxMicCount = 19;
|
||||
break;
|
||||
case RoomType_20Mic:
|
||||
maxMicCount = 20;
|
||||
break;
|
||||
default:
|
||||
maxMicCount = 9; // 默认9麦
|
||||
break;
|
||||
}
|
||||
|
||||
// 获取当前用户及其左右相邻用户的UID
|
||||
NSInteger leftPosition = currentUserMicPosition - 1;
|
||||
NSInteger rightPosition = currentUserMicPosition + 1;
|
||||
|
||||
// 获取左边用户
|
||||
if (leftPosition >= 0) {
|
||||
NSString *leftPositionKey = [NSString stringWithFormat:@"%ld", (long)leftPosition];
|
||||
MicroQueueModel *leftMicModel = queue[leftPositionKey];
|
||||
if (leftMicModel && leftMicModel.userInfo && leftMicModel.userInfo.uid > 0) {
|
||||
[micUserUids addObject:[NSString stringWithFormat:@"%ld", (long)leftMicModel.userInfo.uid]];
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前用户
|
||||
NSString *currentPositionKey = [NSString stringWithFormat:@"%ld", (long)currentUserMicPosition];
|
||||
MicroQueueModel *currentMicModel = queue[currentPositionKey];
|
||||
if (currentMicModel && currentMicModel.userInfo && currentMicModel.userInfo.uid > 0) {
|
||||
[micUserUids addObject:[NSString stringWithFormat:@"%ld", (long)currentMicModel.userInfo.uid]];
|
||||
}
|
||||
|
||||
// 获取右边用户
|
||||
if (rightPosition < maxMicCount) {
|
||||
NSString *rightPositionKey = [NSString stringWithFormat:@"%ld", (long)rightPosition];
|
||||
MicroQueueModel *rightMicModel = queue[rightPositionKey];
|
||||
if (rightMicModel && rightMicModel.userInfo && rightMicModel.userInfo.uid > 0) {
|
||||
[micUserUids addObject:[NSString stringWithFormat:@"%ld", (long)rightMicModel.userInfo.uid]];
|
||||
}
|
||||
}
|
||||
|
||||
// 如果只有当前用户一个人,返回空数据
|
||||
if (micUserUids.count == 1) {
|
||||
NSLog(@"🔧 获取mic用户列表:只有当前用户一个人,返回空数据");
|
||||
return [NSArray array];
|
||||
}
|
||||
|
||||
NSLog(@"🔧 获取mic用户列表:当前用户麦位 %ld,找到 %lu 个相关用户: %@",
|
||||
(long)currentUserMicPosition, (unsigned long)micUserUids.count, micUserUids);
|
||||
return micUserUids;
|
||||
}
|
||||
|
||||
/// 检测并处理下麦事件
|
||||
- (void)handleDownMicEventIfNeeded:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
|
||||
if (!self.stageView || ![self.stageView respondsToSelector:@selector(midpointRectManager)]) {
|
||||
NSLog(@"🔧 处理下麦事件:stageView 不支持 midpointRectManager,跳过处理");
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取当前舞台类型的麦位总数
|
||||
NSInteger micCount = 0;
|
||||
if (self.roomInfo) {
|
||||
switch (self.roomInfo.type) {
|
||||
case RoomType_Game: micCount = 9; break;
|
||||
case RoomType_10Mic: micCount = 10; break;
|
||||
case RoomType_15Mic: micCount = 15; break;
|
||||
case RoomType_19Mic: micCount = 19; break;
|
||||
case RoomType_20Mic: micCount = 20; break;
|
||||
default: micCount = 9; break;
|
||||
}
|
||||
}
|
||||
|
||||
// 使用 MicMidpointRectManager 检测麦位变化
|
||||
// MicMidpointRectManager *midpointRectManager = [self.stageView midpointRectManager];
|
||||
MicMidpointRectManager *midpointRectManager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
|
||||
if (midpointRectManager) {
|
||||
NSDictionary<NSString *, NSArray<NSNumber *> *> *micChanges =
|
||||
[midpointRectManager diffMicChangeWithStageView:self.stageView micCount:micCount];
|
||||
|
||||
NSArray<NSNumber *> *removedUids = micChanges[@"removed"];
|
||||
if (removedUids && removedUids.count > 0) {
|
||||
NSLog(@"🔧 检测到下麦用户:%@", removedUids);
|
||||
|
||||
// 调用 MicMidpointRectManager 处理下麦事件
|
||||
[midpointRectManager handleDownMicEvent:removedUids stageView:self.stageView micCount:micCount];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// mic位变动时调用CP相关API
|
||||
- (void)callMicCpListByUidListOnMicChangeWithQueue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
|
||||
NSLog(@"🔧 mic位变动:开始调用 micCpListByUidList API");
|
||||
|
||||
NSArray<NSString *> *micUserUids = [self getAllMicUserUidsWithQueue:queue];
|
||||
|
||||
if (micUserUids.count == 0) {
|
||||
NSLog(@"🔧 mic位变动:没有相关用户在mic上,跳过API调用");
|
||||
return;
|
||||
}
|
||||
|
||||
// 调用 micCpListByUidList 方法
|
||||
if ([micUserUids containsObject:[AccountInfoStorage instance].getUid]) {
|
||||
NSLog(@"🔧 mic位变动,且包含了当前用户:调用 micCpListByUidList: %@", micUserUids);
|
||||
[self.presenter micCpListByUidList:micUserUids];
|
||||
}
|
||||
|
||||
NSLog(@"🔧 mic位变动:micCpListByUidList API调用完成");
|
||||
}
|
||||
|
||||
/// 初始化当前用户的麦位状态
|
||||
- (void)initializeCurrentUserMicStatus {
|
||||
NSLog(@"🔧 初始化当前用户麦位状态");
|
||||
|
||||
// 重置状态
|
||||
self.currentUserMicStatusChanged = NO;
|
||||
self.currentUserWasOnMic = NO;
|
||||
self.currentUserMicPosition = -1;
|
||||
self.hasCompletedRoomInitialization = NO; // 标记为未完成初始化
|
||||
|
||||
// 获取当前麦位状态
|
||||
NSMutableDictionary<NSString *,MicroQueueModel *> *currentQueue = [self.stageView getMicroQueue];
|
||||
if (currentQueue && currentQueue.count > 0) {
|
||||
NSDictionary *currentStatus = [self getCurrentUserMicStatus:currentQueue];
|
||||
BOOL isOnMic = [currentStatus[@"isOnMic"] boolValue];
|
||||
NSInteger micPosition = [currentStatus[@"micPosition"] integerValue];
|
||||
|
||||
self.currentUserWasOnMic = isOnMic;
|
||||
self.currentUserMicPosition = micPosition;
|
||||
|
||||
NSLog(@"🔧 初始化完成 - 当前用户是否在麦上: %@, 麦位: %ld",
|
||||
isOnMic ? @"是" : @"否", (long)micPosition);
|
||||
} else {
|
||||
NSLog(@"🔧 初始化完成 - 当前没有麦位数据");
|
||||
}
|
||||
|
||||
// 延迟设置初始化完成标志,确保进房时的麦位更新不会触发API调用
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
self.hasCompletedRoomInitialization = YES;
|
||||
NSLog(@"🔧 进房初始化完成,后续麦位变动将触发 micCpListByUidList 调用");
|
||||
});
|
||||
}
|
||||
|
||||
/// 获取当前用户的麦位状态
|
||||
- (NSDictionary *)getCurrentUserMicStatus:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
|
||||
NSInteger currentUid = [AccountInfoStorage instance].getUid.integerValue;
|
||||
BOOL isOnMic = NO;
|
||||
NSInteger micPosition = -1;
|
||||
|
||||
for (NSString *position in queue.allKeys) {
|
||||
MicroQueueModel *micModel = queue[position];
|
||||
if (micModel.userInfo.uid > 0 && micModel.userInfo.uid == currentUid) {
|
||||
isOnMic = YES;
|
||||
micPosition = position.integerValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return @{
|
||||
@"isOnMic": @(isOnMic),
|
||||
@"micPosition": @(micPosition)
|
||||
};
|
||||
}
|
||||
|
||||
/// 检查当前用户麦位状态是否发生变化(上麦、下麦、换位)
|
||||
- (BOOL)checkCurrentUserMicStatusChanged:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
|
||||
NSDictionary *currentStatus = [self getCurrentUserMicStatus:queue];
|
||||
BOOL currentUserOnMic = [currentStatus[@"isOnMic"] boolValue];
|
||||
NSInteger currentMicPosition = [currentStatus[@"micPosition"] integerValue];
|
||||
|
||||
// 情况1:之前不在麦上,现在在麦上(上麦)
|
||||
if (currentUserOnMic && !self.currentUserWasOnMic) {
|
||||
NSLog(@"🔧 检测到当前用户刚刚上麦,麦位: %ld", (long)currentMicPosition);
|
||||
return YES;
|
||||
}
|
||||
|
||||
// 情况2:之前在麦上,现在不在麦上(下麦)
|
||||
if (!currentUserOnMic && self.currentUserWasOnMic) {
|
||||
NSLog(@"🔧 检测到当前用户刚刚下麦,之前麦位: %ld", (long)self.currentUserMicPosition);
|
||||
return YES;
|
||||
}
|
||||
|
||||
// 情况3:之前在麦上,现在也在麦上,但位置不同(换位)
|
||||
if (currentUserOnMic && self.currentUserWasOnMic &&
|
||||
currentMicPosition != self.currentUserMicPosition) {
|
||||
NSLog(@"🔧 检测到当前用户换麦位,从 %ld 换到 %ld",
|
||||
(long)self.currentUserMicPosition, (long)currentMicPosition);
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
/// 更新当前用户的麦位状态
|
||||
- (void)updateCurrentUserMicStatus:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
|
||||
NSDictionary *currentStatus = [self getCurrentUserMicStatus:queue];
|
||||
BOOL currentUserOnMic = [currentStatus[@"isOnMic"] boolValue];
|
||||
NSInteger micPosition = [currentStatus[@"micPosition"] integerValue];
|
||||
|
||||
// 检查麦位状态是否发生变化(上麦、下麦、换位)
|
||||
if ([self checkCurrentUserMicStatusChanged:queue]) {
|
||||
self.currentUserMicStatusChanged = YES;
|
||||
}
|
||||
|
||||
// 更新状态
|
||||
self.currentUserWasOnMic = currentUserOnMic;
|
||||
self.currentUserMicPosition = micPosition;
|
||||
}
|
||||
|
||||
/// 发送麦位关系 NIM message
|
||||
- (void)sendMicRelationshipNIMessage:(NSArray<MicCpInfoModel *> *)cpList {
|
||||
NSLog(@"🔧 发送麦位关系 NIM message,CP数据条数: %ld,当前用户麦位: %ld",
|
||||
(long)cpList.count, (long)self.currentUserMicPosition);
|
||||
|
||||
if (!self.roomInfo) {
|
||||
NSLog(@"⚠️ 发送麦位关系 NIM message:roomInfo为空,跳过发送");
|
||||
return;
|
||||
}
|
||||
|
||||
// 将 CP 数据转换为 JSON string
|
||||
NSMutableArray *cpDataArray = [NSMutableArray array];
|
||||
for (MicCpInfoModel *cpInfo in cpList) {
|
||||
NSDictionary *cpDict = @{
|
||||
@"uid": @(cpInfo.uid),
|
||||
@"loverUid": @(cpInfo.loverUid),
|
||||
@"cpLevel": @(cpInfo.cpLevel)
|
||||
};
|
||||
[cpDataArray addObject:cpDict];
|
||||
}
|
||||
|
||||
NSDictionary *finalData = @{@"first": @(MicRelationship_Type),
|
||||
@"second":@(MicRelationship_CP),
|
||||
@"data":cpDataArray.copy};
|
||||
|
||||
NSError *error = nil;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:finalData options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"❌ 发送麦位关系 NIM message:JSON序列化失败 - %@", error.localizedDescription);
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
NSLog(@"🔧 发送麦位关系 NIM message:JSON数据 - %@", jsonString);
|
||||
|
||||
// 创建 AttachmentModel
|
||||
AttachmentModel *attachment = [[AttachmentModel alloc] init];
|
||||
attachment.first = MicRelationship_Type; // 1001
|
||||
attachment.second = MicRelationship_CP; // 10011
|
||||
attachment.data = jsonString;
|
||||
|
||||
// 创建 NIM message
|
||||
NIMMessage *message = [[NIMMessage alloc] init];
|
||||
NIMCustomObject *object = [[NIMCustomObject alloc] init];
|
||||
object.attachment = attachment;
|
||||
message.messageObject = object;
|
||||
|
||||
// 设置用户信息到 remoteExt
|
||||
UserInfoModel *userInfo = [self getUserInfo];
|
||||
XPMessageRemoteExtModel *extModel = [[XPMessageRemoteExtModel alloc] init];
|
||||
extModel.androidBubbleUrl = userInfo.androidBubbleUrl;
|
||||
extModel.iosBubbleUrl = userInfo.iosBubbleUrl;
|
||||
extModel.fromSayHelloChannel = userInfo.fromSayHelloChannel;
|
||||
extModel.platformRole = userInfo.platformRole;
|
||||
NSMutableDictionary *remoteExt = [NSMutableDictionary dictionaryWithObject:extModel.model2dictionary forKey:[NSString stringWithFormat:@"%ld", userInfo.uid]];
|
||||
message.remoteExt = remoteExt;
|
||||
|
||||
// 构造会话
|
||||
NSString *sessionID = [NSString stringWithFormat:@"%ld", self.roomInfo.roomId];
|
||||
NIMSession *session = [NIMSession session:sessionID type:NIMSessionTypeChatroom];
|
||||
|
||||
// 发送消息
|
||||
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session completion:^(NSError * _Nullable error) {
|
||||
if (error) {
|
||||
NSLog(@"❌ 发送麦位关系 NIM message 失败 - %@", error.localizedDescription);
|
||||
} else {
|
||||
NSLog(@"✅ 发送麦位关系 NIM message 成功");
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
/// 更新 MicMidpointRectManager 的缓存
|
||||
- (void)updateMicMidpointRectManagerCache:(NSArray<MicCpInfoModel *> *)cpList {
|
||||
if (!self.stageView) {
|
||||
NSLog(@"<22><> 更新缓存:stageView 为空,跳过缓存更新");
|
||||
return;
|
||||
}
|
||||
|
||||
MicMidpointRectManager *midpointRectManager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
|
||||
if (midpointRectManager) {
|
||||
// 获取当前用户及其相邻用户的UID列表
|
||||
NSMutableDictionary<NSString *,MicroQueueModel *> *currentQueue = [self.stageView getMicroQueue];
|
||||
NSArray<NSString *> *micUserUids = [self getAllMicUserUidsWithQueue:currentQueue];
|
||||
|
||||
// 转换为 NSNumber 数组
|
||||
NSMutableArray<NSNumber *> *uidNumbers = [NSMutableArray array];
|
||||
for (NSString *uidString in micUserUids) {
|
||||
[uidNumbers addObject:@(uidString.integerValue)];
|
||||
}
|
||||
|
||||
// 更新缓存:先移除相关用户的旧数据,再合并新数据
|
||||
[midpointRectManager mergeCpListCache:cpList replaceForUids:uidNumbers];
|
||||
|
||||
NSLog(@"<22><> 更新缓存完成:CP数据条数 %lu,相关用户 %@",
|
||||
(unsigned long)cpList.count, uidNumbers);
|
||||
}
|
||||
}
|
||||
|
||||
/// 更新 MicMidpointRectManager 的麦位快照
|
||||
- (void)updateMicMidpointRectManagerSnapshot {
|
||||
if (!self.stageView) {
|
||||
NSLog(@"<22><> 更新快照:stageView 为空,跳过快照更新");
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取当前舞台类型的麦位总数
|
||||
NSInteger micCount = 0;
|
||||
if (self.roomInfo) {
|
||||
switch (self.roomInfo.type) {
|
||||
case RoomType_Game: micCount = 9; break;
|
||||
case RoomType_10Mic: micCount = 10; break;
|
||||
case RoomType_15Mic: micCount = 15; break;
|
||||
case RoomType_19Mic: micCount = 19; break;
|
||||
case RoomType_20Mic: micCount = 20; break;
|
||||
default: micCount = 9; break;
|
||||
}
|
||||
}
|
||||
|
||||
MicMidpointRectManager *midpointRectManager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
|
||||
if (midpointRectManager) {
|
||||
[midpointRectManager rebuildMicSnapshotWithStageView:self.stageView micCount:micCount];
|
||||
NSLog(@"🔧 更新麦位快照完成:麦位总数 %ld", (long)micCount);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
Reference in New Issue
Block a user