// // PublicRoomManager.m // YUMI // // Created by YUMI on 2024/12/19. // #import "PublicRoomManager.h" #import "UserInfoModel.h" #import "ClientConfig.h" #import "AccountInfoStorage.h" #import "XPMessageRemoteExtModel.h" @interface PublicRoomManager () @property (nonatomic, assign) BOOL isInitialized; @property (nonatomic, assign) BOOL isInPublicRoom; @property (nonatomic, copy) NSString *currentPublicRoomId; @property (nonatomic, copy) NSString *currentUserId; @property (nonatomic, strong) UserInfoModel *userInfo; @end @implementation PublicRoomManager #pragma mark - 单例方法 + (instancetype)sharedManager { static dispatch_once_t onceToken; static PublicRoomManager *instance; dispatch_once(&onceToken, ^{ instance = [[self alloc] init]; [instance initialize]; }); return instance; } - (instancetype)init { self = [super init]; if (self) { _isInitialized = NO; _isInPublicRoom = NO; _currentPublicRoomId = nil; _currentUserId = nil; _userInfo = nil; } return self; } #pragma mark - 生命周期管理 - (void)initialize { // 防止重复初始化 if (self.isInitialized) { NSLog(@"PublicRoomManager: 已经初始化,跳过重复初始化"); return; } // 检查用户是否已登录 // NSString *uid = [AccountInfoStorage instance].getUid; // if (uid.length == 0) { // NSLog(@"PublicRoomManager: 用户未登录,无法初始化"); // return; // } // 检查是否已获取到用户信息 // UserInfoModel *userInfo = [AccountInfoStorage instance].getHomeUserInfo; // if (!userInfo || !userInfo.partitionId) { // NSLog(@"PublicRoomManager: 用户信息不完整,等待用户信息更新"); // return; // } // 检查配置信息是否已加载 // ClientDataModel *configInfo = [ClientConfig shareConfig].configInfo; // if (!configInfo || !configInfo.publicChatRoomIdMap) { // NSLog(@"PublicRoomManager: 配置信息未加载,等待配置更新"); // return; // } // 保存用户信息 // self.userInfo = userInfo; // self.currentUserId = uid; // 注册云信代理 [[NIMSDK sharedSDK].chatManager addDelegate:self]; // 标记为已初始化 self.isInitialized = YES; // NSLog(@"PublicRoomManager: 初始化成功,用户ID: %@, 分区ID: %@", uid, userInfo.partitionId); // 尝试进入公共房间 // [self tryEnterPublicRoom]; } - (void)reset { NSLog(@"PublicRoomManager: 开始重置"); // 退出公共房间 if (self.isInPublicRoom && self.currentPublicRoomId) { [self exitPublicRoomWithCompletion:^(NSError * _Nullable error) { if (error) { NSLog(@"PublicRoomManager: 退出公共房间失败: %@", error); } else { NSLog(@"PublicRoomManager: 退出公共房间成功"); } }]; } // 移除云信代理 [[NIMSDK sharedSDK].chatManager removeDelegate:self]; // 重置状态 self.isInitialized = NO; self.isInPublicRoom = NO; self.currentPublicRoomId = nil; self.currentUserId = nil; self.userInfo = nil; NSLog(@"PublicRoomManager: 重置完成"); } #pragma mark - 状态查询 - (BOOL)isInitialized { return _isInitialized; } - (BOOL)isInPublicRoom { return _isInPublicRoom; } - (NSString *)currentPublicRoomId { return _currentPublicRoomId; } #pragma mark - 私有方法 - (void)tryEnterPublicRoom { if (!self.isInitialized || !self.userInfo) { NSLog(@"PublicRoomManager: 未初始化或用户信息缺失,无法进入公共房间"); return; } // 获取公共房间ID NSString *partitionId = self.userInfo.partitionId; ClientDataModel *configInfo = [ClientConfig shareConfig].configInfo; NSDictionary *publicChatRoomIdMap = configInfo.publicChatRoomIdMap; if (!publicChatRoomIdMap || !partitionId) { NSLog(@"PublicRoomManager: 公共房间配置或分区ID缺失"); return; } NSNumber *roomId = publicChatRoomIdMap[partitionId]; if (!roomId) { NSLog(@"PublicRoomManager: 未找到分区 %@ 对应的公共房间ID", partitionId); return; } NSLog(@"PublicRoomManager: 尝试进入公共房间,分区ID: %@, 房间ID: %@", partitionId, roomId); // 进入公共房间 [self enterPublicRoomWithRoomId:roomId.stringValue completion:^(NSError * _Nullable error) { if (error) { NSLog(@"PublicRoomManager: 进入公共房间失败: %@", error); } else { NSLog(@"PublicRoomManager: 进入公共房间成功"); } }]; } - (void)enterPublicRoomWithRoomId:(NSString *)roomId completion:(void(^)(NSError * _Nullable error))completion { if (!self.userInfo) { NSError *error = [NSError errorWithDomain:@"PublicRoomManager" code:-1 userInfo:@{NSLocalizedDescriptionKey: @"用户信息缺失"}]; if (completion) { completion(error); } return; } // 创建进房请求 NIMChatroomEnterRequest *request = [[NIMChatroomEnterRequest alloc] init]; request.roomId = roomId; // 设置扩展信息 XPMessageRemoteExtModel *extModel = [[XPMessageRemoteExtModel alloc] init]; extModel.defUser = self.userInfo.defUser; extModel.erbanNo = self.userInfo.erbanNo; extModel.carName = self.userInfo.carName; extModel.inRoomNameplatePic = self.userInfo.nameplatePic; extModel.inRoomNameplateWord = self.userInfo.nameplateWord; extModel.isCustomWord = self.userInfo.isCustomWord; extModel.charmUrl = self.userInfo.userLevelVo.charmUrl; extModel.experLevelSeq = self.userInfo.userLevelVo.experLevelSeq; extModel.experUrl = self.userInfo.userLevelVo.experUrl; extModel.newUser = self.userInfo.newUser; extModel.vipIcon = self.userInfo.userVipInfoVO.nameplateUrl; extModel.iosBubbleUrl = self.userInfo.iosBubbleUrl; extModel.androidBubbleUrl = self.userInfo.androidBubbleUrl; extModel.enterHide = self.userInfo.userVipInfoVO.enterHide; extModel.preventKick = self.userInfo.userVipInfoVO.preventKick; extModel.enterRoomEffects = self.userInfo.userVipInfoVO.enterRoomEffects; extModel.gender = self.userInfo.gender; extModel.fromSayHelloChannel = self.userInfo.fromSayHelloChannel; extModel.platformRole = self.userInfo.platformRole; extModel.nick = self.userInfo.nick; NSMutableDictionary *ext = [NSMutableDictionary dictionaryWithObject:extModel.model2dictionary forKey:[NSString stringWithFormat:@"%ld", self.userInfo.uid]]; request.roomExt = [ext toJSONString]; // 进入房间 @kWeakify(self); [[NIMSDK sharedSDK].chatroomManager enterChatroom:request completion:^(NSError * _Nullable error, NIMChatroom * _Nullable chatroom, NIMChatroomMember * _Nullable me) { @kStrongify(self); dispatch_async(dispatch_get_main_queue(), ^{ if (error) { NSLog(@"PublicRoomManager: 进入公共房间失败: %@", error); if (completion) { completion(error); } } else { NSLog(@"PublicRoomManager: 进入公共房间成功,房间ID: %@", roomId); self.isInPublicRoom = YES; self.currentPublicRoomId = roomId; if (completion) { completion(nil); } } }); }]; } #pragma mark - 手动控制 - (void)enterPublicRoomWithCompletion:(void(^)(NSError * _Nullable error))completion { if (!self.isInitialized) { NSError *error = [NSError errorWithDomain:@"PublicRoomManager" code:-2 userInfo:@{NSLocalizedDescriptionKey: @"管理器未初始化"}]; if (completion) { completion(error); } return; } if (self.isInPublicRoom) { NSLog(@"PublicRoomManager: 已在公共房间中"); if (completion) { completion(nil); } return; } [self tryEnterPublicRoom]; } - (void)exitPublicRoomWithCompletion:(void(^)(NSError * _Nullable error))completion { if (!self.isInPublicRoom || !self.currentPublicRoomId) { NSLog(@"PublicRoomManager: 未在公共房间中"); if (completion) { completion(nil); } return; } @kWeakify(self); [[NIMSDK sharedSDK].chatroomManager exitChatroom:self.currentPublicRoomId completion:^(NSError * _Nullable error) { @kStrongify(self); dispatch_async(dispatch_get_main_queue(), ^{ if (error) { NSLog(@"PublicRoomManager: 退出公共房间失败: %@", error); } else { NSLog(@"PublicRoomManager: 退出公共房间成功"); self.isInPublicRoom = NO; self.currentPublicRoomId = nil; } if (completion) { completion(error); } }); }]; } #pragma mark - 用户信息更新处理 - (void)updateUserInfo:(UserInfoModel *)userInfo { if (!userInfo || !userInfo.partitionId) { NSLog(@"PublicRoomManager: 用户信息更新失败,信息不完整"); return; } // 检查用户是否切换 if (self.currentUserId && ![self.currentUserId isEqualToString:[NSString stringWithFormat:@"%ld", userInfo.uid]]) { NSLog(@"PublicRoomManager: 检测到用户切换,重置管理器"); [self reset]; } self.userInfo = userInfo; self.currentUserId = [NSString stringWithFormat:@"%ld", userInfo.uid]; // 如果已初始化但未在公共房间,尝试进入 if (self.isInitialized && !self.isInPublicRoom) { [self tryEnterPublicRoom]; } } #pragma mark - 配置更新处理 - (void)updateConfig { if (!self.isInitialized) { NSLog(@"PublicRoomManager: 未初始化,跳过配置更新"); return; } ClientDataModel *configInfo = [ClientConfig shareConfig].configInfo; if (!configInfo || !configInfo.publicChatRoomIdMap) { NSLog(@"PublicRoomManager: 配置信息不完整,跳过配置更新"); return; } // 如果未在公共房间,尝试进入 if (!self.isInPublicRoom) { [self tryEnterPublicRoom]; } } #pragma mark - NIMChatManagerDelegate - (void)onRecvMessages:(NSArray *)messages { // 只处理公共房间的消息 for (NIMMessage *message in messages) { if (message.session.sessionType == NIMSessionTypeChatroom) { NSString *sessionId = message.session.sessionId; if ([sessionId isEqualToString:self.currentPublicRoomId]) { NSLog(@"PublicRoomManager: 收到公共房间消息: %@", message.text); // 这里可以添加公共房间消息的处理逻辑 // TODO: 全服广播转移到此类 } } } } @end