426 lines
15 KiB
Objective-C
426 lines
15 KiB
Objective-C
//
|
||
// 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
|