extends Node ## 认证管理器 ## 统一管理用户登录、登出、Token等认证相关功能 # 登录状态枚举 enum LoginState { NOT_LOGGED_IN, # 未登录 LOGGING_IN, # 登录中 LOGGED_IN, # 已登录 GUEST # 游客模式 } # 信号 signal login_success(userData: UserData) signal login_failed(errorCode: int, errorMessage: String) signal logout_success() # 当前登录状态 var currentState: LoginState = LoginState.NOT_LOGGED_IN # Token var accessToken: String = "" var tokenExpireTime: int = 0 # 当前用户信息 var currentUser: UserData = null # 是否正在登录(防止重复请求) var _isLoggingIn: bool = false func _ready(): # 游戏启动时尝试从本地加载 Token 和用户信息 _tryLoadLocalAuth() ## 登录 func login(username: String, password: String, rememberPassword: bool) -> Dictionary: # 防止重复登录 if _isLoggingIn: return { "success": false, "error_code": ErrorCode.INVALID_INPUT, "message": "登录中,请稍候..." } _isLoggingIn = true currentState = LoginState.LOGGING_IN # 构建登录请求数据 var requestData = { "identifier": username, "password": password } # 发送登录请求 var response = await NetworkService.post("/api/auth/login", requestData) _isLoggingIn = false # 处理响应 if response.success: # 解析用户数据和 Token var data = response.get("data", {}) var token = data.get("access_token", "") var userData = data.get("user", {}) if token.is_empty(): var errorMsg = "服务器返回数据格式错误" login_failed.emit(ErrorCode.SERVER_ERROR, errorMsg) currentState = LoginState.NOT_LOGGED_IN return { "success": false, "error_code": ErrorCode.SERVER_ERROR, "message": errorMsg } # 保存 Token accessToken = token tokenExpireTime = int(Time.get_unix_time_from_system()) + 3600 * 24 # 假设24小时过期 StorageService.saveToken(accessToken, tokenExpireTime) # 保存用户信息 currentUser = UserData.fromDict(userData) StorageService.saveUserData(currentUser) # 如果勾选记住密码,保存账号密码 if rememberPassword: StorageService.saveAccount(username, password, true) else: # 只保存用户名,不保存密码 StorageService.save("account", "last_username", username) StorageService.clearSavedPassword() # 更新状态 currentState = LoginState.LOGGED_IN # 发送登录成功信号 login_success.emit(currentUser) return { "success": true, "message": "登录成功", "user": currentUser } else: # 登录失败 var errorCode = response.get("error_code", ErrorCode.WRONG_CREDENTIALS) var errorMsg = response.get("message", "登录失败") currentState = LoginState.NOT_LOGGED_IN login_failed.emit(errorCode, errorMsg) return { "success": false, "error_code": errorCode, "message": errorMsg } ## 登出 func logout() -> void: # 清除 Token 和用户信息 accessToken = "" tokenExpireTime = 0 currentUser = null # 清除本地存储(保留用户名和记住密码设置) StorageService.clearToken() # 更新状态 currentState = LoginState.NOT_LOGGED_IN # 发送登出成功信号 logout_success.emit() print("用户已登出") ## 检查是否已登录 func isLoggedIn() -> bool: return currentState == LoginState.LOGGED_IN and currentUser != null ## 获取当前用户 func getCurrentUser() -> UserData: return currentUser ## 获取当前 Token func getToken() -> String: return accessToken ## 尝试从本地加载认证信息 func _tryLoadLocalAuth() -> void: # 加载 Token var tokenData = StorageService.loadToken() var token = tokenData.get("token", "") var expireTime = tokenData.get("expire_time", 0) # 检查 Token 是否有效 var currentTime = int(Time.get_unix_time_from_system()) if token.is_empty() or expireTime <= currentTime: print("本地 Token 无效或已过期") return # Token 有效,加载用户信息 var userData = StorageService.loadUserData() if userData == null: print("本地用户信息不存在") return # 恢复登录状态 accessToken = token tokenExpireTime = expireTime currentUser = userData currentState = LoginState.LOGGED_IN print("从本地恢复登录状态: ", currentUser.username) # 可选:静默刷新 Token(如果接近过期) # _refreshTokenIfNeeded() ## 检查 Token 是否即将过期 func isTokenExpiring() -> bool: var currentTime = int(Time.get_unix_time_from_system()) var timeLeft = tokenExpireTime - currentTime return timeLeft < 300 # 少于5分钟