Files
peko-ios/YuMi/Modules/YMRoom/Manager/PublicRoomManager.m

426 lines
15 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// PublicRoomManager.m
// YUMI
//
// Created by YUMI on 2024/12/19.
//
#import "PublicRoomManager.h"
#import "UserInfoModel.h"
#import "ClientConfig.h"
#import "AccountModel.h"
#import "AccountInfoStorage.h"
#import "XPMessageRemoteExtModel.h"
#import "AttachmentModel.h"
#import "YUMIConstant.h"
#import "XPSkillCardPlayerManager.h"
@interface PublicRoomManager () <NIMChatroomManagerDelegate, NIMChatManagerDelegate>
@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;
}
// 注册云信代理
[[NIMSDK sharedSDK].chatManager addDelegate:self];
[[NIMSDK sharedSDK].chatroomManager addDelegate:self];
// 标记为已初始化
self.isInitialized = YES;
}
- (BOOL)checkConfigPublicRoomID:(NSString *)partitionId {
ClientDataModel *configInfo = [ClientConfig shareConfig].configInfo;
if (!configInfo || !configInfo.publicChatRoomIdMap) {
NSLog(@"PublicRoomManager: 配置信息未加载,等待配置更新");
return NO;
}
self.currentPublicRoomId = [configInfo.publicChatRoomIdMap objectForKey:partitionId];
return [NSString isEmpty:self.currentPublicRoomId];
}
- (void)reset {
NSLog(@"PublicRoomManager: 开始重置");
// 退出公共房间(同步等待完成)
if (self.isInPublicRoom && self.currentPublicRoomId) {
[self exitPublicRoomWithCompletion:^(NSError * _Nullable error) {
if (error) {
NSLog(@"PublicRoomManager: 退出公共房间失败: %@", error);
} else {
NSLog(@"PublicRoomManager: 退出公共房间成功");
self.currentUserId = nil;
self.userInfo = nil;
NSLog(@"PublicRoomManager: 重置完成");
}
}];
} else {
NSLog(@"PublicRoomManager: 不在房间,不处理");
}
// 重置状态
self.isInitialized = NO;
self.isInPublicRoom = NO;
self.currentPublicRoomId = nil;
}
#pragma mark - 状态查询
- (BOOL)isInitialized {
return _isInitialized;
}
- (BOOL)isInPublicRoom {
return _isInPublicRoom;
}
- (NSString *)currentPublicRoomId {
return _currentPublicRoomId;
}
#pragma mark - 私有方法
- (void)tryEnterPublicRoom {
NSLog(@"PublicRoomManager: 开始尝试进入公共房间");
NSLog(@"PublicRoomManager: 当前状态 - isInitialized: %@, isInPublicRoom: %@, currentPublicRoomId: %@",
self.isInitialized ? @"YES" : @"NO",
self.isInPublicRoom ? @"YES" : @"NO",
self.currentPublicRoomId ?: @"nil");
if (!self.isInitialized) {
NSLog(@"PublicRoomManager: 管理器未初始化,无法进入公共房间");
return;
}
if (!self.userInfo) {
NSLog(@"PublicRoomManager: 用户信息缺失,无法进入公共房间");
return;
}
// 获取公共房间ID
NSString *partitionId = self.userInfo.partitionId;
ClientDataModel *configInfo = [ClientConfig shareConfig].configInfo;
NSDictionary *publicChatRoomIdMap = configInfo.publicChatRoomIdMap;
NSLog(@"PublicRoomManager: 配置信息 - partitionId: %@, configInfo: %@, publicChatRoomIdMap: %@",
partitionId ?: @"nil",
configInfo ? @"存在" : @"nil",
publicChatRoomIdMap ? @"存在" : @"nil");
if (!publicChatRoomIdMap) {
NSLog(@"PublicRoomManager: 公共房间配置缺失");
return;
}
if (!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: 进入公共房间成功房间ID: %@", roomId.stringValue);
}
}];
}
- (void)enterPublicRoomWithRoomId:(NSString *)roomId completion:(void(^)(NSError * _Nullable error))completion {
if (!self.userInfo) {
NSError *error = [NSError errorWithDomain:@"PublicRoomManager"
code:-1
userInfo:@{NSLocalizedDescriptionKey: @"用户信息缺失 nnn"}];
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;
}
NSLog(@"PublicRoomManager: room id-%@ 正在尝试退出公共房间", self.currentPublicRoomId);
@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 {
NSLog(@"PublicRoomManager: 开始更新用户信息");
NSLog(@"PublicRoomManager: 用户信息 - uid: %ld, partitionId: %@",
userInfo.uid, userInfo.partitionId ?: @"nil");
if (!userInfo) {
NSLog(@"PublicRoomManager: 用户信息为空,更新失败");
return;
}
if (!userInfo.partitionId) {
NSLog(@"PublicRoomManager: 用户分区ID缺失更新失败");
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 checkConfigPublicRoomID:@(userInfo.uid).stringValue]) {
return;
}
NSLog(@"PublicRoomManager: 用户信息更新完成 - currentUserId: %@, isInitialized: %@, isInPublicRoom: %@",
self.currentUserId,
self.isInitialized ? @"YES" : @"NO",
self.isInPublicRoom ? @"YES" : @"NO");
// 注释掉自动进入房间逻辑,改为统一入口控制
// 如果已初始化但未在公共房间,尝试进入
// if (self.isInitialized && !self.isInPublicRoom) {
// NSLog(@"PublicRoomManager: 条件满足,开始尝试进入公共房间");
// [self tryEnterPublicRoom];
// } else {
// NSLog(@"PublicRoomManager: 条件不满足,跳过进入公共房间 - isInitialized: %@, isInPublicRoom: %@",
// self.isInitialized ? @"YES" : @"NO",
// self.isInPublicRoom ? @"YES" : @"NO");
// }
}
#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 - NIMChatRoomManagerDelegate
#define ConnectionStateStyleString(enum) \
[@[@"Entering", @"EnterOK", @"EnterFailed", @"LoseConnection"] objectAtIndex:(enum)]
- (void)chatroom:(NSString *)roomId connectionStateChanged:(NIMChatroomConnectionState)state {
NSLog(@"PublicRoomManager 房间连接状态: %@", ConnectionStateStyleString(state));
}
#pragma mark - NIMChatManagerDelegate
- (void)onRecvMessages:(NSArray<NIMMessage *> *)messages {
// 只处理公共房间的消息
for (NIMMessage *message in messages) {
if (message.session.sessionType == NIMSessionTypeChatroom) {
NSString *sessionId = message.session.sessionId;
if ([sessionId isEqualToString:self.currentPublicRoomId]) {
NIMMessageChatroomExtension *messageExt = (NIMMessageChatroomExtension *)message.messageExt;
AttachmentModel *attachment;
if (message.messageType == NIMMessageTypeCustom) {
NIMCustomObject *obj = (NIMCustomObject *) message.messageObject;
attachment = (AttachmentModel *) obj.attachment;
if (attachment) {
switch (attachment.first) {
case CustomMessageType_Super_Gift:
[self handleFirst_106:attachment
message:message];
break;
default:
break;
}
}
}
// NSLog(@"PublicRoomManager: 收到公共房间消息: %@\n%@",
// message.rawAttachContent,
// messageExt.roomExt);
}
}
}
}
- (void)handleFirst_106:(AttachmentModel *)attachment
message:(NIMMessage *)message {
// 只有用户在房间时,才会转发
if (![XPSkillCardPlayerManager shareInstance].isInRoom) {
NSLog(@"PublicRoomManager: 用户未在房间中,跳过消息转发");
return;
}
switch (attachment.second) {
case Custom_Message_Sub_Super_Gift:
[[NSNotificationCenter defaultCenter] postNotificationName:@"MessageFromPublicRoomWithAttachmentNotification"
object:message];
NSLog(@"PublicRoomManager: 转发 106 - 1061 类型消息到房间");
break;
default:
break;
}
}
@end