// // XPRoomViewController.m // xplan-ios // // Created by 冯硕 on 2021/10/11. // #import "XPRoomViewController.h" ///Third #import #import ///Tool #import "XPMacro.h" #import "XPConstant.h" #import "AccountInfoStorage.h" #import "RtcManager.h" #import "XPRoomMiniManager.h" #import "TTPopup.h" #import "Api+ArrangeMic.h" #import "Api+Room.h" #import "DESEncrypt.h" ///Model #import "RoomInfoModel.h" #import "UserInfoModel.h" #import "AttachmentModel.h" #import "ArrangeMicModel.h" #import "XPReleaseRadioModel.h" #import "XPNobleTrumpetModel.h" #import "GuildSuperAdminInfoModel.h" #import "XPKickUserModel.h" ///View #import "BaseNavigationController.h" #import "XPRoomActivityContainerView.h" #import "XPRoomBackContainerView.h" #import "XPRoomMenuContainerView.h" #import "XPRoomMessageContainerView.h" #import "RoomHeaderView.h" #import "SocialStageView.h" #import "DatingStageView.h" #import "AnchorStageView.h" #import "LittleGameStageView.h" #import "AnchorPkStageView.h" #import "LittleGameScrollStageView.h" #import "XPRoomAnimationView.h" #import "XPRoomFunctionContainerView.h" #import "XPArrangeMicViewController.h" #import "XPRoomSettingInputView.h" #import "XPRoomLittleGameContainerView.h" ///P #import "XPRoomPresenter.h" #import "XPRoomProtocol.h" #import "RoomHostDelegate.h" #import "RoomGuestDelegate.h" UIKIT_EXTERN NSString * const kRoomGiftEffectUpdateNotificationKey; UIKIT_EXTERN NSString * const kRoomMiniNotificationKey; @interface XPRoomViewController () ///背景 @property (nonatomic,strong) XPRoomBackContainerView *backContainerView; ///房间信息 @property (nonatomic,strong) RoomHeaderView *roomHeaderView; ///坑位信息 @property (nonatomic,strong) StageView *stageView; ///公屏 @property (nonatomic,strong) XPRoomMessageContainerView *messageContainerView; ///底部操作栏 @property (nonatomic,strong) XPRoomMenuContainerView *menuContainerView; ///活动 @property (nonatomic,strong) XPRoomActivityContainerView *activityContainerView; ///动画的view @property (nonatomic,strong) XPRoomAnimationView *animationView; ///功能view的的容器 @property (nonatomic,strong) XPRoomFunctionContainerView *functionView; ///小游戏的容器 @property (nonatomic,strong) XPRoomLittleGameContainerView *littleGameView; ///房间的Uid @property (nonatomic,copy) NSString * roomUid; ///小游戏的id @property (nonatomic,copy) NSString *mgId; ///用户信息 @property (nonatomic,strong) UserInfoModel *userInfo; ///房间信息 @property (nonatomic,strong) RoomInfoModel *roomInfo; ///本地是否修改过礼物特效显示 当前房间如果设置过礼物特效是否显示的话 就不再跟随房间礼物特效的更新而更新 @property (nonatomic,assign) BOOL hasAnimationEffect; ///跟随的 @property (nonatomic,copy) NSString *fromNick; @property (nonatomic,assign) UserEnterRoomFromType fromType; @property (nonatomic,copy) NSString *fromUid; ///超管列表 @property (nonatomic,strong) NSArray *superMangerList; ///是否请求过了超管 @property (nonatomic,assign) BOOL isRequestSuperAdmin; @end @implementation XPRoomViewController + (BOOL)openRoom:(NSString *)roomUid viewController:(UIViewController *)viewController { return [self openRoom:roomUid fromNick:nil fromType:0 fromUid:nil viewController:viewController]; } + (BOOL)openRoom:(NSString*)roomUid fromNick:(NSString * __nullable)fromNick fromType:(UserEnterRoomFromType)fromType fromUid:(NSString * __nullable)fromUid viewController:(UIViewController*)viewController { XPRoomViewController * roomVC = [[self alloc] init]; roomVC.roomUid = roomUid; roomVC.fromUid = fromUid; roomVC.fromType = fromType; roomVC.fromNick = fromNick; BaseNavigationController * baseNav = [[BaseNavigationController alloc] initWithRootViewController:roomVC]; baseNav.modalPresentationStyle = UIModalPresentationFullScreen; [viewController presentViewController:baseNav animated:YES completion:nil]; return YES; } /** XPRoomViewController 不允许外部 init ,请通过该方法启动房间。 * @params roomUid 房主uid * @params viewController 启动方 * @params mgId 小游戏的id */ + (BOOL)openRoom:(NSString*)roomUid mgId:(NSString *)mgId viewController:(UIViewController*)viewController { XPRoomViewController * roomVC = [[self alloc] init]; roomVC.roomUid = roomUid; roomVC.mgId = mgId; BaseNavigationController * baseNav = [[BaseNavigationController alloc] initWithRootViewController:roomVC]; baseNav.modalPresentationStyle = UIModalPresentationFullScreen; [viewController presentViewController:baseNav animated:YES completion:nil]; return YES; } - (void)dealloc { #warning to dox - 时刻注意这个方法 功能做完的时候删除此方法 } - (XPRoomPresenter *)createPresenter { return [[XPRoomPresenter alloc] init]; } - (BOOL)isHiddenNavBar { return YES; } - (void)viewDidLoad { [super viewDidLoad]; [self exitOldRoom]; [self initSubViews]; [self initSubViewConstraints]; [self.presenter initEnterRoom:self.roomUid user:[AccountInfoStorage instance].getUid]; /// 公屏 福袋礼物爆出的礼物 需要依赖 当前房间中的礼物列表 需要提前获取礼物列表 可以拿到礼物 没有想到别的方法去解决这个问题 有需要改的在修改吧 [self.presenter getNormalGiftList:self.roomUid]; ///获取房间超管列表 [self.presenter getRoomSuperAdmin:self.roomUid]; //监听云信消息 [[NIMSDK sharedSDK].chatroomManager addDelegate:self]; [[NIMSDK sharedSDK].chatManager addDelegate:self]; [[NIMSDK sharedSDK].loginManager addDelegate:self]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myGiftEffectUpdate:) name:kRoomGiftEffectUpdateNotificationKey object:nil]; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self.view endEditing:YES]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent; } #pragma mark - Private Method - (void)initSubViews { [self.view addSubview:self.backContainerView]; [self.view addSubview:self.littleGameView]; [self.view addSubview:self.stageView]; [self.view addSubview:self.messageContainerView]; [self.view addSubview:self.menuContainerView]; [self.view addSubview:self.activityContainerView]; [self.view addSubview:self.roomHeaderView]; [self.view addSubview:self.functionView]; [self.view addSubview:self.animationView]; } - (void)initSubViewConstraints { [self.backContainerView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.mas_equalTo(self.view); }]; [self.roomHeaderView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.top.mas_equalTo(self.view); make.height.mas_equalTo(kNavigationHeight); }]; [self.stageView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.mas_equalTo(self.view); make.top.mas_equalTo(self.roomHeaderView.mas_bottom); make.height.mas_equalTo(self.stageView.hightForStageView); }]; [self.messageContainerView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.stageView.mas_bottom); make.bottom.equalTo(self.menuContainerView.mas_top).offset(-5); make.left.equalTo(self.view); make.right.equalTo(self.activityContainerView.mas_left).offset(-10); }]; [self.menuContainerView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.mas_equalTo(self.view); make.bottom.mas_equalTo(-kSafeAreaBottomHeight- 8); make.height.mas_equalTo(40); }]; [self.activityContainerView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(self.messageContainerView); make.right.mas_equalTo(self.view); make.bottom.mas_equalTo(self.menuContainerView.mas_top).offset(-5); make.width.mas_equalTo(80); }]; [self.animationView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.mas_equalTo(self.view); }]; [self.functionView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.mas_equalTo(self.view); }]; [self.littleGameView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.mas_equalTo(self.view); }]; } - (void)exitOldRoom { NSString * roomUid = [NSString stringWithFormat:@"%ld", [XPRoomMiniManager shareManager].getRoomInfo.uid]; if (roomUid.integerValue > 0 && roomUid.integerValue != self.roomUid.integerValue) { //有最小化房间 并且要进入的房间和最小化的房间不一样的话 就先退掉 最小化的房间 NSString * roomId = [NSString stringWithFormat:@"%ld", [XPRoomMiniManager shareManager].getRoomInfo.roomId]; [self.presenter exitNIMRoom:roomId]; [[RtcManager instance] exitRoom]; [[XPRoomMiniManager shareManager] resetLocalMessage]; [self.presenter reportUserOutRoom:roomUid]; } } - (void)userEnterRoomSuccess { AttachmentModel *attachment = [[AttachmentModel alloc]init]; attachment.first = CustomMessageType_Car_Notify; attachment.second = Custom_Message_Sub_Car_EnterRoom; NSMutableDictionary *att = [NSMutableDictionary dictionary]; if (self.userInfo.userVipInfoVO.enterHide) {///贵族隐身进房,不发座驾消息 return; } if (self.userInfo.viewUrl.length > 0) { [att setValue:self.userInfo.nick forKey:@"nick"]; [att setValue:self.userInfo.viewUrl forKey:@"viewUrl"]; [att setValue:@(self.userInfo.otherViewType) forKey:@"otherViewType"]; } else if (self.userInfo.carEffect.length > 0) { [att setValue:self.userInfo.carEffect forKey:@"effect"]; [att setValue:self.userInfo.nick forKey:@"nick"]; } else { return; } attachment.data = att; NSString *sessionID = [NSString stringWithFormat:@"%ld",self.roomInfo.roomId]; NIMMessage *message = [[NIMMessage alloc]init]; NIMCustomObject *object = [[NIMCustomObject alloc] init]; object.attachment = attachment; message.messageObject = object; //构造会话 NIMSession *session = [NIMSession session:sessionID type:NIMSessionTypeChatroom]; [[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil]; } - (void)changeStageViewOnRoomUpdate { if (self.roomInfo.roomModeType == RoomModeType_Open_Blind && ![self.stageView isKindOfClass:[DatingStageView class]]) { [self.stageView removeFromSuperview]; self.stageView = nil; self.stageView = [[DatingStageView alloc] initWithDelegate:self]; } else if(self.roomInfo.datingState == RoomDatingStateChangeType_Close && ![self.stageView isKindOfClass:[SocialStageView class]]) { [self.stageView removeFromSuperview]; self.stageView = nil; self.stageView = [[SocialStageView alloc] initWithDelegate:self]; } else if (self.roomInfo.type == RoomType_Anchor) { if (self.roomInfo.roomModeType == RoomModeType_Open_AcrossRoomPK_mode && ![self.stageView isKindOfClass:[AnchorPKStageView class]]) { [self.stageView removeFromSuperview]; self.stageView = nil; self.stageView = [[AnchorPKStageView alloc] initWithDelegate:self]; } else if(self.roomInfo.roomModeType == RoomModeType_Normal_Mode && ![self.stageView isKindOfClass:[AnchorStageView class]]) { [self.stageView removeFromSuperview]; self.stageView = nil; self.stageView = [[AnchorStageView alloc] initWithDelegate:self]; } } else if(self.roomInfo.type == RoomType_MiniGame) { if (self.roomInfo.mgMicNum > 6 && ![self.stageView isKindOfClass:[LittleGameScrollStageView class]]) { [self.stageView removeFromSuperview]; self.stageView = nil; self.stageView = [[LittleGameScrollStageView alloc] initWithDelegate:self]; } else if (self.roomInfo.mgMicNum <= 6 && ![self.stageView isKindOfClass:[LittleGameStageView class]]) { [self.stageView removeFromSuperview]; self.stageView = nil; self.stageView = [[LittleGameStageView alloc] initWithDelegate:self]; } }else if(self.roomInfo.hadChangeRoomType && ![self.stageView isKindOfClass:[SocialStageView class]]) { [self.stageView removeFromSuperview]; self.stageView = nil; self.stageView = [[SocialStageView alloc] initWithDelegate:self]; } else { return; } if (!self.stageView.superview) { [self.view insertSubview:self.stageView belowSubview:self.roomHeaderView]; } if (self.roomInfo.type == RoomType_MiniGame) { [self.stageView mas_remakeConstraints:^(MASConstraintMaker *make) { make.left.right.mas_equalTo(self.view); make.top.mas_equalTo(self.roomHeaderView.mas_bottom).offset(26 + 4); make.height.mas_equalTo(self.stageView.hightForStageView); }]; [self.messageContainerView mas_remakeConstraints:^(MASConstraintMaker *make) { make.height.mas_equalTo(70); make.bottom.mas_equalTo(self.menuContainerView.mas_top).offset(-5); make.left.mas_equalTo(self.view); make.right.mas_equalTo(self.activityContainerView.mas_left).offset(-10); }]; [self.activityContainerView mas_remakeConstraints:^(MASConstraintMaker *make) { make.height.mas_equalTo(65); make.right.mas_equalTo(self.view); make.bottom.mas_equalTo(self.menuContainerView.mas_top).offset(-5); make.width.mas_equalTo(80); }]; } else { [self.stageView mas_remakeConstraints:^(MASConstraintMaker *make) { make.left.right.mas_equalTo(self.view); make.top.mas_equalTo(self.roomHeaderView.mas_bottom); make.height.mas_equalTo(self.stageView.hightForStageView); }]; [self.messageContainerView mas_remakeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(self.stageView.mas_bottom); make.bottom.mas_equalTo(self.menuContainerView.mas_top).offset(-5); make.left.mas_equalTo(self.view); make.right.mas_equalTo(self.activityContainerView.mas_left).offset(-10); }]; [self.activityContainerView mas_remakeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(self.messageContainerView); make.right.mas_equalTo(self.view); make.bottom.mas_equalTo(self.menuContainerView.mas_top).offset(-5); make.width.mas_equalTo(80); }]; } } - (void)cancelRoomArrangeMic { ///退出排麦 if (self.roomInfo.roomModeType == RoomModeType_Open_Micro_Mode || self.roomInfo.roomModeType == RoomModeType_Open_Blind) { NSString * roomUid = [NSString stringWithFormat:@"%ld", self.roomInfo.uid]; NSString * uid = [AccountInfoStorage instance].getUid; [Api getRoomArrangeMicList:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) { if (code == 200) { ArrangeMicModel * arrangeMicModel= [ArrangeMicModel modelWithJSON:data.data]; if (arrangeMicModel.myPos.intValue > 0) { __block NSString * grouptype = @"0"; if (self.roomInfo.roomModeType == RoomModeType_Open_Blind) { [arrangeMicModel.queue enumerateObjectsUsingBlock:^(ArrangeMicUserModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if (obj.uid.integerValue == [AccountInfoStorage instance].getUid.integerValue) { grouptype = [NSString stringWithFormat:@"%ld", obj.groupType]; *stop = YES; } }]; } [Api cancelArrangeMic:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {} roomUid:roomUid operUid:uid groupType:grouptype]; } } } roomUid:roomUid operUid:uid page:@"1" pageSize:@"50"]; } } ///超管进入密码房间 - (void)superAdminEnterPwdRoom:(RoomInfoModel *)roomInfo { __block BOOL isSuperAdmin = NO; [self.superMangerList enumerateObjectsUsingBlock:^(GuildSuperAdminInfoModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if ([obj.uid isEqualToString:[AccountInfoStorage instance].getUid]) { isSuperAdmin = YES; *stop = YES; } }]; if (!isSuperAdmin) { XPRoomSettingInputView * titleView = [[XPRoomSettingInputView alloc] init]; titleView.maxCount = 15; titleView.delegate = self; titleView.type = RoomSettingInputType_Input_Pwd; TTPopupConfig * config = [[TTPopupConfig alloc] init]; config.contentView = titleView; config.maskBackgroundAlpha = 1; config.shouldDismissOnBackgroundTouch = NO; [TTPopup popupWithConfig:config]; } else { self.roomInfo.datingState = roomInfo.roomModeType == RoomModeType_Open_Blind ? RoomDatingStateChangeType_Open : RoomDatingStateChangeType_Normal; [self changeStageViewOnRoomUpdate]; [self.roomHeaderView onRoomEntered]; [self.activityContainerView onRoomEntered]; [self.menuContainerView onRoomEntered]; [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]; [self.functionView onRoomEntered]; [self.messageContainerView onRoomEntered]; } else { //虽然没退出房间 但是队列还是要拿的 [self.stageView onRoomEntered]; [self.messageContainerView onRoomMiniEntered]; [self.functionView onRoomEntered]; } [[XPRoomMiniManager shareManager] configRoomInfo:nil]; } } #pragma mark - 本地礼物特效更新 - (void)myGiftEffectUpdate:(NSNotification *)notification { NSDictionary * dic = notification.object; self.roomInfo.hasAnimationEffect = ((NSNumber *)dic[@"hasAnimationEffect"]).boolValue; self.hasAnimationEffect = self.roomInfo.hasAnimationEffect; [self.roomHeaderView onRoomUpdate]; } #pragma mark - XPRoomProtocol - (void)initEnterRoomSuccess:(RoomInfoModel *)roomInfo user:(UserInfoModel *)userInfo { userInfo.fromUid = self.fromUid; userInfo.fromType = self.fromType; userInfo.fromNick = self.fromNick; self.hasAnimationEffect = roomInfo.hasAnimationEffect; self.roomInfo = roomInfo; self.userInfo = userInfo; if (roomInfo.valid) { // 房间有效,直接进入房间 if (roomInfo.roomPwd.length > 0 && roomInfo.uid != [AccountInfoStorage instance].getUid.integerValue && [XPRoomMiniManager shareManager].getRoomInfo.uid != self.roomUid.integerValue) {//进房密码的情况 if (!self.isRequestSuperAdmin) { [Api getRoomSuperAdminList:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) { NSArray * array = [GuildSuperAdminInfoModel modelsWithArray:data.data]; self.superMangerList = array; [self superAdminEnterPwdRoom:roomInfo]; } roomUid:self.roomUid]; } else { [self superAdminEnterPwdRoom:roomInfo]; } } else { self.roomInfo.datingState = roomInfo.roomModeType == RoomModeType_Open_Blind ? RoomDatingStateChangeType_Open : RoomDatingStateChangeType_Normal; [self changeStageViewOnRoomUpdate]; [self.roomHeaderView onRoomEntered]; [self.activityContainerView onRoomEntered]; [self.menuContainerView onRoomEntered]; [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]; [self.functionView onRoomEntered]; [self.messageContainerView onRoomEntered]; } else { //虽然没退出房间 但是队列还是要拿的 [self.stageView onRoomEntered]; [self.messageContainerView onRoomMiniEntered]; [self.functionView onRoomEntered]; } [[XPRoomMiniManager shareManager] configRoomInfo:nil]; } } else { // 房间无效,分是否为自己房间进行处理 if ([self.roomUid isEqualToString:[NSString stringWithFormat:@"%ld", userInfo.uid]]) { // 当前用户进入自己房间 if (roomInfo.roomId > 0) { // 存在房间信息,直接使用房间信息开房 if (roomInfo.type == RoomType_MiniGame && roomInfo.mgId > 0) { self.mgId = [NSString stringWithFormat:@"%lld", roomInfo.mgId]; } [self.presenter openRoom:roomInfo.title type:roomInfo.type roomPwd:roomInfo.roomPwd roomDesc:roomInfo.roomDesc backPic:@"" mgId:self.mgId]; } else { // 不存在房间信息,全新开房 NSString* title = [NSString stringWithFormat:@"%@的房间", userInfo.nick]; RoomType type = RoomType_Game; if (self.mgId.length > 0) { type = RoomType_MiniGame; } [self.presenter openRoom:title type:type roomPwd:@"" roomDesc:@"" backPic:@"" mgId:self.mgId]; } } else { // 当前用户进入别人房间 // TODO: 房主已经下线。 [self showSuccessToast:@"房主已下线"]; [self enterRoomFail:0]; } } } - (void)openRoomSuccess:(RoomInfoModel *)roomInfo { self.roomInfo = roomInfo; [self changeStageViewOnRoomUpdate]; [self.roomHeaderView onRoomEntered]; [self.activityContainerView onRoomEntered]; [self.backContainerView onRoomEntered]; [self.littleGameView onRoomEntered]; [self.functionView onRoomEntered]; [self.messageContainerView onRoomEntered]; [self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo]; } - (void)enterRoomSuccess:(NIMChatroom *)chatRoom { // room/get中的房间在线人数 是定时更新的 不是及时刷新 self.roomInfo.onlineNum = chatRoom.onlineUserCount; [self.stageView onRoomEntered]; //上报进房 if (self.roomInfo != nil) { [self.presenter reportUserInterRoom:[NSString stringWithFormat:@"%zd", self.roomInfo.uid]]; } } - (void)enterRoomFail:(NSInteger)code { if (code == 13003) { [self showErrorToast:@"您已被管理员拉黑"]; } [self dismissViewControllerAnimated:YES completion:nil]; } ///请求房间超管成功 ///这个接口本来是想和roominfo 和userinfo 一起请求的 但是 进房的同步操作 只有超管进入密码房间才会有同步的问题 - (void)getRoomSuperAdminScuccess:(NSArray *)list { self.isRequestSuperAdmin = YES; self.superMangerList = list; } #pragma mark - NIMChatroomManagerDelegate - (void)chatroomBeKicked:(NIMChatroomBeKickedResult *)result { if (result.reason == 2) { [self showErrorToast:@"您被管理员踢出直播间"]; } else if (result.reason == 5) { [self showErrorToast:@"您已被管理员拉黑"]; } [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[XPRoomMiniManager shareManager] resetLocalMessage]; [self cancelRoomArrangeMic]; [[RtcManager instance] exitRoom]; [self.presenter reportUserOutRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.uid]]; [self.littleGameView handleSelfInExitEvent]; [self.littleGameView destroyMG]; [self dismissViewControllerAnimated:YES completion:nil]; } #pragma mark - NIMChatManagerDelegate - (void)onRecvMessages:(NSArray *)messages { for (NIMMessage * message in messages) { // 非房间内消息不处理 if (message.session.sessionType != NIMSessionTypeChatroom) { continue; } // 非本房间不处理 if (![message.session.sessionId isEqualToString:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]) { continue; } if (message.messageType == NIMMessageTypeNotification) { NIMNotificationObject *notiMsg = (NIMNotificationObject *)message.messageObject; NIMChatroomNotificationContent *content = (NIMChatroomNotificationContent *)notiMsg.content; NSInteger onLineNumber = self.roomInfo.onlineNum; switch (content.eventType) { case NIMChatroomEventTypeInfoUpdated: // 麦序状态更新 { NSDictionary *data = [content.notifyExt toJSONObject]; int type = [data[@"type"] intValue]; switch (type) { case 1: case 3: { NSMutableDictionary *lastRoomInfoDic = [NSMutableDictionary dictionaryWithDictionary:[self.roomInfo model2dictionary]]; [lastRoomInfoDic addEntriesFromDictionary: ((NSString *)data[@"roomInfo"]).toJSONObject]; RoomInfoModel *newRoomInfo = [RoomInfoModel modelWithJSON:lastRoomInfoDic]; //TODO: 从小游戏房间切换到普通房间的话 mgid不会被清除掉 if (newRoomInfo.type != RoomType_MiniGame) { newRoomInfo.mgId = 0; } newRoomInfo.hasAnimationEffect = self.hasAnimationEffect; if (newRoomInfo.roomModeType == RoomModeType_Open_Blind && self.roomInfo.roomModeType != RoomModeType_Open_Blind) { ///普通房 切换为相亲房 newRoomInfo.datingState = RoomDatingStateChangeType_Open; } else if(newRoomInfo.roomModeType != RoomModeType_Open_Blind && self.roomInfo.roomModeType == RoomModeType_Open_Blind) { ///关闭了相亲房 newRoomInfo.datingState = RoomDatingStateChangeType_Close; } else { newRoomInfo.datingState = RoomDatingStateChangeType_Normal; } //房间类型是否变更了(从个播->普通,个播->小游戏等) newRoomInfo.hadChangeRoomType = self.roomInfo.type != newRoomInfo.type; self.roomInfo = newRoomInfo; [self.backContainerView onRoomUpdate]; [self changeStageViewOnRoomUpdate]; [self.stageView onRoomUpdate]; [self.menuContainerView onRoomUpdate]; [self.functionView onRoomUpdate]; [self.activityContainerView onRoomUpdate]; [self.messageContainerView onRoomUpdate]; [self.littleGameView onRoomUpdate]; } break; } } break; case NIMChatroomEventTypeEnter: if (content.source.userId.integerValue != [AccountInfoStorage instance].getUid.integerValue) { onLineNumber += 1; }else {///如果是自己的话 如果有坐骑的话 [self userEnterRoomSuccess]; ///在活动页面 判断是否显示 相亲加入的按钮 所以需要等用户进房成功之后才能获取 房间角色 [self.activityContainerView onRoomUpdate]; [self.menuContainerView onRoomUpdate]; } break; case NIMChatroomEventTypeAddBlack: case NIMChatroomEventTypeKicked: case NIMChatroomEventTypeExit: onLineNumber -= 1; break; case NIMChatroomEventTypeQueueChange: // 麦序上下麦 { NSDictionary* data = (NSDictionary *)content.ext; UserInfoModel* userInfo = [UserInfoModel modelWithJSON:[data objectForKey:NIMChatroomEventInfoQueueChangeItemValueKey]]; NSInteger changeType = [data[NIMChatroomEventInfoQueueChangeTypeKey] integerValue]; if (changeType == 1 && userInfo.uid == [AccountInfoStorage instance].getUid.integerValue) { [self cancelRoomArrangeMic]; } } break; default: break; } self.roomInfo.onlineNum = onLineNumber; [self.roomHeaderView onRoomUpdate]; [self.stageView handleNIMNotificationMessage:message]; [self.animationView handleNIMNotificationMessage:message]; [self.messageContainerView handleNIMNotificationMessage:message]; [self.activityContainerView handleNIMNotificationMessage:message]; [self.menuContainerView handleNIMNotificationMessage:message]; [self.functionView handleNIMNotificationMessage:message]; [self.littleGameView handleNIMNotificationMessage:message]; } else if (message.messageType == NIMMessageTypeCustom) { NIMCustomObject *obj = (NIMCustomObject *)message.messageObject; if (obj.attachment != nil && [obj.attachment isKindOfClass:[AttachmentModel class]]) { AttachmentModel * attachment = obj.attachment; [self.stageView handleNIMCustomMessage:message]; [self.animationView handleNIMCustomMessage:message]; [self.menuContainerView handleNIMCustomMessage:message]; [self.activityContainerView handleNIMCustomMessage:message]; [self.functionView handleNIMCustomMessage:message]; [self.littleGameView handleNIMCustomMessage:message]; if (attachment.first == CustomMessageType_First_Recharge_Reward && attachment.second == Custom_Message_Sub_Room_First_Recharge_Reward) { self.userInfo.isFirstCharge = NO; [self.menuContainerView onRoomUpdate]; [self.activityContainerView onRoomUpdate]; } else if (attachment.first == CustomMessageType_Update_RoomInfo && attachment.second == Custom_Message_Sub_Update_RoomInfo_MessageState) { ///兼容安卓和iOS 协议不同的问题 NSDictionary * dic= attachment.data[@"roomInfo"]; if (dic.allKeys.count <=0) { dic = attachment.data; } RoomInfoModel * roomInfo = [RoomInfoModel modelWithDictionary:dic]; self.roomInfo.isCloseScreen = roomInfo.isCloseScreen; [self.menuContainerView onRoomUpdate]; } else if(attachment.first == CustomMessageType_Queue && attachment.second == Custom_Message_Sub_Queue_Invite) { NSDictionary *dic = attachment.data; NSString *uid = dic[@"uid"]; if (uid.integerValue == [AccountInfoStorage instance].getUid.integerValue) { [self cancelRoomArrangeMic]; } } else if(attachment.first == CustomMessageType_Hall_Super_Admin && attachment.second == Custom_Message_Sub_Hall_Super_Admin_Kick_Manager_Out_Room) { XPKickUserModel * userInfo = [XPKickUserModel modelWithJSON:attachment.data]; if (userInfo.targetUid == [AccountInfoStorage instance].getUid.integerValue) { [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[XPRoomMiniManager shareManager] resetLocalMessage]; [self cancelRoomArrangeMic]; [[RtcManager instance] exitRoom]; [self.presenter reportUserOutRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.uid]]; [self.littleGameView handleSelfInExitEvent]; [self.littleGameView destroyMG]; [self dismissViewControllerAnimated:YES completion:nil]; } } [self.messageContainerView handleNIMCustomMessage:message]; } } else if(message.messageType == NIMMessageTypeText) { [self.messageContainerView handleNIMTextMessage:message]; } else if(message.messageType == NIMMessageTypeTip) { [self.messageContainerView handleNIMTextMessage:message]; } } } //发送消息成功回调 - (void)sendMessage:(NIMMessage *)message didCompleteWithError:(NSError *)error { // 非本房间不处理 if (![message.session.sessionId isEqualToString:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]) { return; } if (error) return; if (message.messageType == NIMMessageTypeCustom) { NIMCustomObject *obj = (NIMCustomObject *)message.messageObject; if (obj.attachment != nil && [obj.attachment isKindOfClass:[AttachmentModel class]]) { AttachmentModel * attachment = obj.attachment; [self.stageView handleNIMCustomMessage:message]; [self.animationView handleNIMCustomMessage:message]; [self.functionView handleNIMCustomMessage:message]; if (attachment.first == CustomMessageType_Update_RoomInfo && attachment.second == Custom_Message_Sub_Update_RoomInfo_MessageState) { RoomInfoModel * roomInfo = [RoomInfoModel modelWithDictionary:attachment.data[@"roomInfo"]]; self.roomInfo.isCloseScreen = roomInfo.isCloseScreen; [self.menuContainerView onRoomUpdate]; } [self.messageContainerView handleNIMCustomMessage:message]; } }else if(message.messageType == NIMMessageTypeText) { [self.messageContainerView handleNIMTextMessage:message]; [self.littleGameView handleNIMTextMessage:message]; } } #pragma mark - NIMLoginManagerDelegate - (void)onKickout:(NIMLoginKickoutResult *)result { [self exitRoom]; [self dismissViewControllerAnimated:YES completion:nil]; } #pragma mark - RoomDelegate - (RoomInfoModel *)getRoomInfo { return self.roomInfo; } - (UserInfoModel *)getUserInfo { return self.userInfo; } - (void)exitRoom { if (self.roomInfo.roomModeType == RoomModeType_Open_Micro_Mode || self.roomInfo.roomModeType == RoomModeType_Open_Blind) { NSString * roomUid = [NSString stringWithFormat:@"%ld", self.roomInfo.uid]; NSString * uid = [AccountInfoStorage instance].getUid; [Api getRoomArrangeMicList:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) { if (code == 200) { ArrangeMicModel * arrangeMicModel= [ArrangeMicModel modelWithJSON:data.data]; if (arrangeMicModel.myPos.intValue > 0) { [TTPopup alertWithMessage:@"退出房间后将退出目前排麦,再次进入需要重新排麦,确认退出房间吗?" confirmHandler:^{ __block NSString * grouptype = @"0"; if (self.roomInfo.roomModeType == RoomModeType_Open_Blind) { [arrangeMicModel.queue enumerateObjectsUsingBlock:^(ArrangeMicUserModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if (obj.uid.integerValue == [AccountInfoStorage instance].getUid.integerValue) { grouptype = [NSString stringWithFormat:@"%ld", obj.groupType]; *stop = YES; } }]; } [Api cancelArrangeMic:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) { } roomUid:roomUid operUid:uid groupType:grouptype]; [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[XPRoomMiniManager shareManager] resetLocalMessage]; [[RtcManager instance] exitRoom]; [self.presenter reportUserOutRoom:roomUid]; [self dismissViewControllerAnimated:YES completion:nil]; } cancelHandler:^{ }]; return; } } [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[XPRoomMiniManager shareManager] resetLocalMessage]; [[RtcManager instance] exitRoom]; [self.presenter reportUserOutRoom:roomUid]; [self dismissViewControllerAnimated:YES completion:nil]; } roomUid:roomUid operUid:uid page:@"1" pageSize:@"50"]; } else if(self.roomInfo.type == RoomType_MiniGame) { if ([self.littleGameView isInSudGame]) { TTAlertConfig *config = [[TTAlertConfig alloc] init]; config.cancelButtonConfig.title = @"取消"; config.confirmButtonConfig.title = @"确认"; config.message = @"退出房间则默认认输逃跑,是否退房?"; [TTPopup alertWithConfig:config confirmHandler:^{ // 知道了 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[RtcManager instance] exitRoom]; [self.littleGameView handleSelfInExitEvent]; [self.littleGameView destroyMG]; [self dismissViewControllerAnimated:YES completion:nil]; }); } cancelHandler:^{ }]; } else { [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[RtcManager instance] exitRoom]; [self.littleGameView handleSelfInExitEvent]; [self.littleGameView destroyMG]; [self dismissViewControllerAnimated:YES completion:nil]; } } else { [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[XPRoomMiniManager shareManager] resetLocalMessage]; [[RtcManager instance] exitRoom]; [self.presenter reportUserOutRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.uid]]; [self dismissViewControllerAnimated:YES completion:nil]; } } - (void)miniRoom { if(self.roomInfo.type == RoomType_MiniGame) { if ([self.littleGameView isInSudGame]) { TTAlertConfig *config = [[TTAlertConfig alloc] init]; config.cancelButtonConfig.title = @"取消"; config.confirmButtonConfig.title = @"确认"; config.message = @"退出房间则默认认输逃跑,是否退房?"; [TTPopup alertWithConfig:config confirmHandler:^{ // 知道了 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [[XPRoomMiniManager shareManager] configRoomInfo:self.roomInfo]; NSDictionary * dic = @{@"roomInfo":self.roomInfo.model2dictionary, @"userInfo":self.userInfo.model2dictionary, @"microQueue":self.getMicroQueue}; [[NSNotificationCenter defaultCenter] postNotificationName:kRoomMiniNotificationKey object:nil userInfo:dic]; [self.view endEditing:YES]; [self.littleGameView handleSelfInExitEvent]; [self.littleGameView destroyMG]; [self dismissViewControllerAnimated:YES completion:nil]; }); } cancelHandler:^{ }]; } else { [[XPRoomMiniManager shareManager] configRoomInfo:self.roomInfo]; NSDictionary * dic = @{@"roomInfo":self.roomInfo.model2dictionary, @"userInfo":self.userInfo.model2dictionary, @"microQueue":self.getMicroQueue}; [[NSNotificationCenter defaultCenter] postNotificationName:kRoomMiniNotificationKey object:nil userInfo:dic]; [self.view endEditing:YES]; [self.littleGameView handleSelfInExitEvent]; [self.littleGameView destroyMG]; [self dismissViewControllerAnimated:YES completion:nil]; } }else { [[XPRoomMiniManager shareManager] configRoomInfo:self.roomInfo]; NSDictionary * dic = @{@"roomInfo":self.roomInfo.model2dictionary, @"userInfo":self.userInfo.model2dictionary, @"microQueue":self.getMicroQueue}; [[NSNotificationCenter defaultCenter] postNotificationName:kRoomMiniNotificationKey object:nil userInfo:dic]; [self.view endEditing:YES]; [self dismissViewControllerAnimated:YES completion:nil]; } } - (UINavigationController *)getCurrentNav { return self.navigationController; } - (NSMutableDictionary *)getMicroQueue { return [self.stageView getMicroQueue]; } - (NSArray *)getRoomSuperAdminList { return self.superMangerList; } - (void)onMicroQueueUpdate:(NSMutableDictionary *)queue { [self.menuContainerView onMicroQueueUpdate:queue]; [self.functionView onRoomUpdate]; [self.functionView onMicroQueueUpdate:queue]; } - (CGPoint)animationPointAtStageViewByUid:(NSString *)uid { return [self.stageView animationPointAtStageViewByUid:uid]; } #pragma mark - XPRoomLittleGameContainerViewDelegate - (void)hiddenSudGamePostionView { [self.functionView hiddenSudGamePostionView]; } #pragma mark - XPRoomSettingInputViewDelegate ///点击了完成 - (void)xPRoomSettingInputView:(XPRoomSettingInputView *)view didClickConfirm:(NSString *)text type:(RoomSettingInputType)type { NSString *pwdDes = [DESEncrypt encryptUseDES:text key:KeyWithType(KeyType_PasswordEncode)]; if ([pwdDes isEqualToString:self.roomInfo.roomPwd]) { [TTPopup dismiss]; view.isPwdError = NO; [self.roomHeaderView onRoomEntered]; [self.activityContainerView onRoomEntered]; [self.menuContainerView onRoomEntered]; [self changeStageViewOnRoomUpdate]; [self.backContainerView onRoomEntered]; [self.functionView onRoomEntered]; [self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo]; [self.messageContainerView onRoomEntered]; [self.littleGameView onRoomEntered]; [[XPRoomMiniManager shareManager] configRoomInfo:nil]; } else { view.isPwdError = YES; } } - (void)didClickCancel:(RoomSettingInputType)type { if (type == RoomSettingInputType_Input_Pwd) { [self enterRoomFail:0]; } } - (XPRoomBackContainerView *)backContainerView { if (!_backContainerView) { _backContainerView = [[XPRoomBackContainerView alloc] initWithdelegate:self]; } return _backContainerView; } - (RoomHeaderView *)roomHeaderView { if (!_roomHeaderView) { _roomHeaderView = [[RoomHeaderView alloc] initWithDelegate:self]; } return _roomHeaderView; } - (XPRoomMessageContainerView *)messageContainerView { if (!_messageContainerView) { _messageContainerView = [[XPRoomMessageContainerView alloc] initWithDelegate:self]; } return _messageContainerView; } - (XPRoomMenuContainerView *)menuContainerView { if (!_menuContainerView) { _menuContainerView = [[XPRoomMenuContainerView alloc] initWithDelegate:self]; } return _menuContainerView; } - (XPRoomActivityContainerView *)activityContainerView { if (!_activityContainerView) { _activityContainerView = [[XPRoomActivityContainerView alloc] initWithdelegate:self]; } return _activityContainerView; } - (XPRoomAnimationView *)animationView { if (!_animationView) { _animationView = [[XPRoomAnimationView alloc] initWithDelegate:self]; } return _animationView; } - (XPRoomFunctionContainerView *)functionView { if (!_functionView) { _functionView = [[XPRoomFunctionContainerView alloc] initWithdelegate:self]; } return _functionView; } - (StageView *)stageView { if (!_stageView) { _stageView = [[SocialStageView alloc] initWithDelegate:self]; } return _stageView; } - (XPRoomLittleGameContainerView *)littleGameView { if (!_littleGameView) { _littleGameView = [[XPRoomLittleGameContainerView alloc] initWithDelegate:self]; _littleGameView.delegate = self; } return _littleGameView; } @end