Files
peko-ios/YuMi/Modules/YMRoom/View/MoreView/Manager/TurboModeStateManager.m

524 lines
20 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.

//
// TurboModeStateManager.m
// YuMi
//
// Created by Linus on 2025/1/13.
//
#import "TurboModeStateManager.h"
#import "XPTurboModeConstants.h"
@interface TurboModeStateManager ()
@property (nonatomic, assign) BOOL globalTurboEnabled; // 全局 turbo 模式
@property (nonatomic, strong) NSMutableDictionary<NSString *, NSDictionary *> *roomSwitchStates; // 所有房间的开关状态
@property (nonatomic, copy) NSString *currentUserId; // 当前用户ID
@property (nonatomic, copy) NSString *currentRoomId;
@end
@implementation TurboModeStateManager
#pragma mark - Singleton
+ (instancetype)sharedManager {
static TurboModeStateManager *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[TurboModeStateManager alloc] init];
});
return instance;
}
- (instancetype)init {
if (self = [super init]) {
// 🔧 修复按照规则2app启动后首次初始化时turbo mode为关闭状态
// 只有在用户主动操作过turbo mode后才从缓存加载
self.globalTurboEnabled = NO;
self.roomSwitchStates = [NSMutableDictionary dictionary];
self.currentUserId = nil;
}
return self;
}
#pragma mark - Public Methods
// 🔧 新增:启动 TurboModeStateManager在用户登录成功后调用
- (void)startupWithCurrentUser:(NSString *)userId {
if (!userId) return;
self.currentUserId = userId;
[self loadAllRoomSwitchStates];
NSLog(@"🎮 TurboModeStateManager: 已启动用户ID: %@", userId);
}
// 🔧 新增:加载所有房间的开关状态
- (void)loadAllRoomSwitchStates {
if (!self.currentUserId) return;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *prefix = [NSString stringWithFormat:@"Turbo_%@_", self.currentUserId];
// 遍历所有 UserDefaults 中的 key找到属于当前用户的房间开关状态
NSDictionary *allDefaults = [defaults dictionaryRepresentation];
for (NSString *key in allDefaults.allKeys) {
if ([key hasPrefix:prefix] && [key containsString:@"_Room_"]) {
// 提取房间ID
NSString *roomId = [self extractRoomIdFromKey:key];
if (roomId) {
[self loadSwitchStatesForRoom:roomId];
}
}
}
NSLog(@"🎮 TurboModeStateManager: 已加载 %lu 个房间的开关状态", (unsigned long)self.roomSwitchStates.count);
}
// 🔧 新增:更新礼物特效开关状态(通过 RoomInfo.hasAnimationEffect 更新)
- (void)updateGiftEffectsForRoom:(NSString *)roomId enabled:(BOOL)enabled {
if (!roomId) return;
[self ensureRoomSwitchStatesExist:roomId];
NSMutableDictionary *roomStates = [self.roomSwitchStates[roomId] mutableCopy];
roomStates[@"giftEffects"] = @(enabled);
self.roomSwitchStates[roomId] = roomStates;
// 🔧 修复发送通知以便UI能够更新
[[NSNotificationCenter defaultCenter] postNotificationName:kTurboGiftEffectsEnabledChanged
object:nil
userInfo:@{ @"roomId": roomId, @"on": @(enabled) }];
NSLog(@"🎮 TurboModeStateManager: 房间 %@ 礼物特效开关更新为 %@", roomId, enabled ? @"开启" : @"关闭");
}
// 向后兼容:默认视为非用户来源
- (void)updateGiftEffectsForRoom:(NSString *)roomId enabled:(BOOL)enabled fromUser:(BOOL)fromUser {
if (!roomId) return;
[self ensureRoomSwitchStatesExist:roomId];
NSMutableDictionary *roomStates = [self.roomSwitchStates[roomId] mutableCopy];
roomStates[@"giftEffects"] = @(enabled);
if (fromUser) {
roomStates[@"giftEffectsOverride"] = @(YES);
}
self.roomSwitchStates[roomId] = roomStates;
[[NSNotificationCenter defaultCenter] postNotificationName:kTurboGiftEffectsEnabledChanged
object:nil
userInfo:@{ @"roomId": roomId, @"on": @(enabled) }];
NSLog(@"🎮 TurboModeStateManager: 房间 %@ 礼物特效开关更新为 %@ (fromUser=%@)", roomId, enabled ? @"开启" : @"关闭", fromUser ? @"YES" : @"NO");
}
// 用户覆盖标记控制
- (void)setGiftEffectsOverrideForRoom:(NSString *)roomId enabled:(BOOL)enabled {
if (!roomId) return;
[self ensureRoomSwitchStatesExist:roomId];
NSMutableDictionary *roomStates = [self.roomSwitchStates[roomId] mutableCopy];
roomStates[@"giftEffectsOverride"] = @(enabled);
self.roomSwitchStates[roomId] = roomStates;
}
- (BOOL)isGiftEffectsUserOverriddenForRoom:(NSString *)roomId {
if (!roomId) return NO;
[self ensureRoomSwitchStatesExist:roomId];
return [self.roomSwitchStates[roomId][@"giftEffectsOverride"] boolValue];
}
// 🔧 修复获取礼物特效开关状态考虑全局turbo mode影响
- (BOOL)isGiftEffectsEnabledForRoom:(NSString *)roomId {
if (!roomId) return NO;
[self ensureRoomSwitchStatesExist:roomId];
// 如果全局turbo mode开启所有非CP开关都应该关闭
if ([self isTurboModeEnabled]) {
return NO;
}
// 否则返回本地状态
return [self.roomSwitchStates[roomId][@"giftEffects"] boolValue];
}
// 🔧 修复获取全局礼物屏幕开关状态考虑全局turbo mode影响
- (BOOL)isGlobalGiftScreenEnabledForRoom:(NSString *)roomId {
if (!roomId) return NO;
[self ensureRoomSwitchStatesExist:roomId];
// 如果全局turbo mode开启所有非CP开关都应该关闭
if ([self isTurboModeEnabled]) {
return NO;
}
// 否则返回本地状态
return [self.roomSwitchStates[roomId][@"globalGiftScreen"] boolValue];
}
// 🔧 修复获取全局游戏屏幕开关状态考虑全局turbo mode影响
- (BOOL)isGlobalGameScreenEnabledForRoom:(NSString *)roomId {
if (!roomId) return NO;
[self ensureRoomSwitchStatesExist:roomId];
// 如果全局turbo mode开启所有非CP开关都应该关闭
if ([self isTurboModeEnabled]) {
return NO;
}
// 否则返回本地状态
return [self.roomSwitchStates[roomId][@"globalGameScreen"] boolValue];
}
// 🔧 新增获取CP麦位开关状态
- (BOOL)isCpMicEnabledForRoom:(NSString *)roomId {
if (!roomId) return NO;
[self ensureRoomSwitchStatesExist:roomId];
return [self.roomSwitchStates[roomId][@"cpMic"] boolValue];
}
// 🔧 新增:设置全局礼物屏幕开关
- (void)setGlobalGiftScreenEnabledForRoom:(NSString *)roomId enabled:(BOOL)enabled {
if (!roomId) return;
[self ensureRoomSwitchStatesExist:roomId];
NSMutableDictionary *roomStates = [self.roomSwitchStates[roomId] mutableCopy];
roomStates[@"globalGiftScreen"] = @(enabled);
self.roomSwitchStates[roomId] = roomStates;
// 持久化到 NSUserDefaults
[[NSUserDefaults standardUserDefaults] setBool:enabled forKey:kTurboGlobalGiftScreenEnabledKey(roomId)];
[[NSUserDefaults standardUserDefaults] synchronize];
// 发送通知
[[NSNotificationCenter defaultCenter] postNotificationName:kTurboGlobalGiftScreenEnabledChanged
object:nil
userInfo:@{@"on": @(enabled), @"roomId": roomId}];
NSLog(@"🎮 TurboModeStateManager: 房间 %@ 全局礼物屏幕开关设置为 %@", roomId, enabled ? @"开启" : @"关闭");
}
// 🔧 新增:设置全局游戏屏幕开关
- (void)setGlobalGameScreenEnabledForRoom:(NSString *)roomId enabled:(BOOL)enabled {
if (!roomId) return;
[self ensureRoomSwitchStatesExist:roomId];
NSMutableDictionary *roomStates = [self.roomSwitchStates[roomId] mutableCopy];
roomStates[@"globalGameScreen"] = @(enabled);
self.roomSwitchStates[roomId] = roomStates;
// 持久化到 NSUserDefaults
[[NSUserDefaults standardUserDefaults] setBool:enabled forKey:kTurboGlobalGameScreenEnabledKey(roomId)];
[[NSUserDefaults standardUserDefaults] synchronize];
// 发送通知
[[NSNotificationCenter defaultCenter] postNotificationName:kTurboGlobalGameScreenEnabledChanged
object:nil
userInfo:@{@"on": @(enabled), @"roomId": roomId}];
NSLog(@"🎮 TurboModeStateManager: 房间 %@ 全局游戏屏幕开关设置为 %@", roomId, enabled ? @"开启" : @"关闭");
}
// 🔧 新增设置CP麦位开关
- (void)setCpMicEnabledForRoom:(NSString *)roomId enabled:(BOOL)enabled {
if (!roomId) return;
[self ensureRoomSwitchStatesExist:roomId];
NSMutableDictionary *roomStates = [self.roomSwitchStates[roomId] mutableCopy];
roomStates[@"cpMic"] = @(enabled);
self.roomSwitchStates[roomId] = roomStates;
// 持久化到 NSUserDefaults
[[NSUserDefaults standardUserDefaults] setBool:enabled forKey:kTurboCpMicEnabledKey(roomId)];
[[NSUserDefaults standardUserDefaults] synchronize];
// 发送通知
[[NSNotificationCenter defaultCenter] postNotificationName:kTurboCpMicEnabledChanged
object:nil
userInfo:@{@"on": @(enabled), @"roomId": roomId}];
NSLog(@"🎮 TurboModeStateManager: 房间 %@ CP麦位开关设置为 %@", roomId, enabled ? @"开启" : @"关闭");
}
- (void)setTurboModeEnabled:(BOOL)enabled {
self.globalTurboEnabled = enabled;
[[NSUserDefaults standardUserDefaults] setBool:enabled forKey:@"TurboMode_Global"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(@"🎮 TurboModeStateManager: 全局 turbo mode 设置为 %@", enabled ? @"开启" : @"关闭");
// 发送状态变化通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"TurboModeStateChanged"
object:nil
userInfo:@{@"enabled": @(enabled)}];
}
// 🔧 新增:静默设置 turbo mode 状态,不发送通知
- (void)setTurboModeEnabledSilently:(BOOL)enabled {
self.globalTurboEnabled = enabled;
[[NSUserDefaults standardUserDefaults] setBool:enabled forKey:@"TurboMode_Global"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(@"🎮 TurboModeStateManager: 全局 turbo mode 静默设置为 %@", enabled ? @"开启" : @"关闭");
}
- (BOOL)isTurboModeEnabled {
return self.globalTurboEnabled;
}
- (void)applyTurboModeToSwitchesForRoom:(NSString *)roomId {
if (!roomId) return;
BOOL turboModeEnabled = [self isTurboModeEnabled];
if (turboModeEnabled) {
// turbo mode = YES仅影响非CP三开关
[self forceCloseAllSwitches:roomId];
NSLog(@"🎮 TurboModeStateManager: 应用 turbo mode房间 %@ 的3个非CP开关全部关闭", roomId);
} else {
// turbo mode = NO仅影响非CP三开关
[self forceOpenAllSwitches:roomId];
NSLog(@"🎮 TurboModeStateManager: turbo mode 关闭,房间 %@ 的3个非CP开关全部打开", roomId);
}
}
- (NSDictionary<NSString *, NSNumber *> *)getSwitchStatesAfterTurboModeForRoom:(NSString *)roomId {
if (!roomId) return @{};
BOOL turboModeEnabled = [self isTurboModeEnabled];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// 礼物特效:按需求不持久化,这里默认开启(面板或 RoomAnimationView 会基于 roomInfo 决定)
BOOL giftEffects = YES;
BOOL giftEffectsOverride = NO;
id giftScreenObj = [defaults objectForKey:kTurboGlobalGiftScreenEnabledKey(roomId)];
BOOL globalGiftScreen = (giftScreenObj != nil) ? [defaults boolForKey:kTurboGlobalGiftScreenEnabledKey(roomId)] : NO;
id gameScreenObj = [defaults objectForKey:kTurboGlobalGameScreenEnabledKey(roomId)];
BOOL globalGameScreen = (gameScreenObj != nil) ? [defaults boolForKey:kTurboGlobalGameScreenEnabledKey(roomId)] : NO;
id cpMicObj = [defaults objectForKey:kTurboCpMicEnabledKey(roomId)];
BOOL cpMic = (cpMicObj != nil) ? [defaults boolForKey:kTurboCpMicEnabledKey(roomId)] : NO;
if (turboModeEnabled) {
return @{
@"giftEffects": @(NO),
@"globalGiftScreen": @(NO),
@"globalGameScreen": @(NO),
@"cpMic": @(cpMic)
};
} else {
return @{
@"giftEffects": @(giftEffects),
@"globalGiftScreen": @(globalGiftScreen),
@"globalGameScreen": @(globalGameScreen),
@"cpMic": @(cpMic)
};
}
}
- (void)resetTurboMode {
self.globalTurboEnabled = NO;
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"TurboMode_Global"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(@"🎮 TurboModeStateManager: 全局 turbo mode 状态已重置");
}
#pragma mark - Private Methods
- (void)forceCloseAllSwitches:(NSString *)roomId {
if (!roomId) return;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// 🔧 修复强制关闭所有开关并更新roomSwitchStates
[self ensureRoomSwitchStatesExist:roomId];
NSMutableDictionary *roomStates = [self.roomSwitchStates[roomId] mutableCopy];
// 强制关闭礼物特效开关:不持久化,只更新内存状态
roomStates[@"giftEffects"] = @(NO);
// 强制关闭全局礼物屏幕开关
roomStates[@"globalGiftScreen"] = @(NO);
[defaults setBool:NO forKey:kTurboGlobalGiftScreenEnabledKey(roomId)];
// 强制关闭全局游戏屏幕开关
roomStates[@"globalGameScreen"] = @(NO);
[defaults setBool:NO forKey:kTurboGlobalGameScreenEnabledKey(roomId)];
// 不改动 CP 麦位开关
self.roomSwitchStates[roomId] = roomStates;
[defaults synchronize];
// 发送通知,让相关组件更新状态
[self sendSwitchStateChangeNotifications:roomId];
}
- (void)forceOpenAllSwitches:(NSString *)roomId {
if (!roomId) return;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// 🔧 修复强制打开所有开关并更新roomSwitchStates
[self ensureRoomSwitchStatesExist:roomId];
NSMutableDictionary *roomStates = [self.roomSwitchStates[roomId] mutableCopy];
// 强制打开礼物特效开关:不持久化,只更新内存状态
roomStates[@"giftEffects"] = @(YES);
// 强制打开全局礼物屏幕开关
roomStates[@"globalGiftScreen"] = @(YES);
[defaults setBool:YES forKey:kTurboGlobalGiftScreenEnabledKey(roomId)];
// 强制打开全局游戏屏幕开关
roomStates[@"globalGameScreen"] = @(YES);
[defaults setBool:YES forKey:kTurboGlobalGameScreenEnabledKey(roomId)];
// 不改动 CP 麦位开关
self.roomSwitchStates[roomId] = roomStates;
[defaults synchronize];
// 发送通知,让相关组件更新状态
[self sendSwitchStateChangeNotificationsForOpen:roomId];
}
- (void)sendSwitchStateChangeNotifications:(NSString *)roomId {
// 发送礼物特效开关状态变化通知
[[NSNotificationCenter defaultCenter]
postNotificationName:kTurboGiftEffectsEnabledChanged
object:nil
userInfo:@{@"on": @(NO), @"roomId": roomId}];
// 发送全局礼物屏幕开关状态变化通知
[[NSNotificationCenter defaultCenter]
postNotificationName:kTurboGlobalGiftScreenEnabledChanged
object:nil
userInfo:@{@"on": @(NO), @"roomId": roomId}];
// 发送全局游戏屏幕开关状态变化通知
[[NSNotificationCenter defaultCenter]
postNotificationName:kTurboGlobalGameScreenEnabledChanged
object:nil
userInfo:@{@"on": @(NO), @"roomId": roomId}];
// 不发送 CP 麦位开关状态变化通知
}
- (void)sendSwitchStateChangeNotificationsForOpen:(NSString *)roomId {
// 发送礼物特效开关状态变化通知
[[NSNotificationCenter defaultCenter]
postNotificationName:kTurboGiftEffectsEnabledChanged
object:nil
userInfo:@{@"on": @(YES), @"roomId": roomId}];
// 发送全局礼物屏幕开关状态变化通知
[[NSNotificationCenter defaultCenter]
postNotificationName:kTurboGlobalGiftScreenEnabledChanged
object:nil
userInfo:@{@"on": @(YES), @"roomId": roomId}];
// 发送全局游戏屏幕开关状态变化通知
[[NSNotificationCenter defaultCenter]
postNotificationName:kTurboGlobalGameScreenEnabledChanged
object:nil
userInfo:@{@"on": @(YES), @"roomId": roomId}];
// 不发送 CP 麦位开关状态变化通知
}
- (void)loadTurboModeStatesFromCache {
// 不再按房间加载,已改为全局
}
// 🔧 新增:从 key 中提取房间ID
- (NSString *)extractRoomIdFromKey:(NSString *)key {
// key 格式: Turbo_UserId_Room_RoomId_GlobalGiftScreen
NSArray *components = [key componentsSeparatedByString:@"_"];
if (components.count >= 4) {
// 找到 "Room" 的位置
NSInteger roomIndex = -1;
for (NSInteger i = 0; i < components.count; i++) {
if ([components[i] isEqualToString:@"Room"]) {
roomIndex = i;
break;
}
}
if (roomIndex != -1 && roomIndex + 1 < components.count) {
return components[roomIndex + 1];
}
}
return nil;
}
// 🔧 新增:确保房间开关状态存在
- (void)ensureRoomSwitchStatesExist:(NSString *)roomId {
if (!roomId) return;
if (!self.roomSwitchStates[roomId]) {
[self loadSwitchStatesForRoom:roomId];
}
}
// 🔧 新增:加载指定房间的开关状态
- (void)loadSwitchStatesForRoom:(NSString *)roomId {
if (!roomId) return;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// 礼物特效:从房间信息获取,这里先设为默认值
BOOL giftEffects = YES;
BOOL giftEffectsOverride = NO;
// 其他三个开关:从 NSUserDefaults 读取
id giftScreenObj = [defaults objectForKey:kTurboGlobalGiftScreenEnabledKey(roomId)];
BOOL globalGiftScreen = (giftScreenObj != nil) ? [defaults boolForKey:kTurboGlobalGiftScreenEnabledKey(roomId)] : NO;
id gameScreenObj = [defaults objectForKey:kTurboGlobalGameScreenEnabledKey(roomId)];
BOOL globalGameScreen = (gameScreenObj != nil) ? [defaults boolForKey:kTurboGlobalGameScreenEnabledKey(roomId)] : NO;
id cpMicObj = [defaults objectForKey:kTurboCpMicEnabledKey(roomId)];
BOOL cpMic = (cpMicObj != nil) ? [defaults boolForKey:kTurboCpMicEnabledKey(roomId)] : NO;
self.roomSwitchStates[roomId] = @{
@"giftEffects": @(giftEffects),
@"giftEffectsOverride": @(giftEffectsOverride),
@"globalGiftScreen": @(globalGiftScreen),
@"globalGameScreen": @(globalGameScreen),
@"cpMic": @(cpMic)
};
}
#pragma mark - 当前房间ID管理
// 🔧 新增设置当前房间ID进房成功后调用
- (void)setCurrentRoomId:(NSString *)roomId {
if (!roomId) return;
if ([roomId isEqualToString:_currentRoomId]) {
return;
}
_currentRoomId = roomId;
// 🔧 修复按照规则1进房后先读取缓存状态然后应用turbo mode的影响
[self ensureRoomSwitchStatesExist:roomId];
[self applyTurboModeToSwitchesForRoom:roomId];
// 发送通知告知其他组件房间ID已设置
[[NSNotificationCenter defaultCenter] postNotificationName:kTurboCurrentRoomIdSet
object:nil
userInfo:@{@"roomId": roomId}];
NSLog(@"🎮 TurboModeStateManager: 设置当前房间ID: %@已应用turbo mode影响", roomId);
}
// 🔧 新增获取当前房间ID
- (NSString *)loadCurrentRoomId {
return self.currentRoomId;
}
@end