import 'dart:io'; import 'package:PiliPlus/models/common/account_type.dart'; import 'package:PiliPlus/pages/mine/controller.dart'; import 'package:PiliPlus/utils/accounts/account.dart'; import 'package:PiliPlus/utils/login_utils.dart'; import 'package:PiliPlus/utils/storage.dart'; import 'package:cookie_jar/cookie_jar.dart'; import 'package:flutter/foundation.dart'; import 'package:hive/hive.dart'; import 'package:path_provider/path_provider.dart'; class Accounts { static late final Box account; static final Map accountMode = {}; static Account get main => accountMode[AccountType.main]!; // static set main(Account account) => set(AccountType.main, account); static Future init() async { account = await Hive.openBox('account', compactionStrategy: (int entries, int deletedEntries) { return deletedEntries > 2; }); await _migrate(); } static Future _migrate() async { final Directory tempDir = await getApplicationSupportDirectory(); final String tempPath = "${tempDir.path}/.plpl/"; final Directory dir = Directory(tempPath); if (dir.existsSync()) { if (kDebugMode) debugPrint('migrating...'); final cookieJar = PersistCookieJar(ignoreExpires: true, storage: FileStorage(tempPath)); await cookieJar.forceInit(); final cookies = DefaultCookieJar(ignoreExpires: true) ..domainCookies.addAll(cookieJar.domainCookies); final localAccessKey = GStorage.localCache.get('accessKey', defaultValue: {}); final isLogin = cookies.domainCookies['bilibili.com']?['/']?['SESSDATA'] != null; await Future.wait([ GStorage.localCache.delete('accessKey'), GStorage.localCache.delete('danmakuFilterRule'), GStorage.localCache.delete('blackMidsList'), dir.delete(recursive: true), if (isLogin) LoginAccount(cookies, localAccessKey['value'], localAccessKey['refresh'], AccountType.values.toSet()) .onChange() ]); if (kDebugMode) debugPrint('migrated successfully'); } } static void refresh() { for (var a in account.values) { for (var t in a.type) { accountMode[t] = a; } } for (var type in AccountType.values) { accountMode[type] ??= AnonymousAccount(); } // await Future.wait((accountMode.values.toSet() // ..retainWhere((i) => !i.activited)) // .map((i) => Request.buvidActive(i))); } static Future clear() async { await account.clear(); for (var i in AccountType.values) { accountMode[i] = AnonymousAccount(); } await AnonymousAccount().delete(); // Request.buvidActive(AnonymousAccount()); } static void close() { account ..compact() ..close(); } static Future deleteAll(Set accounts) async { var isloginMain = Accounts.main.isLogin; Accounts.accountMode .updateAll((_, a) => accounts.contains(a) ? AnonymousAccount() : a); await Future.wait(accounts.map((i) => i.delete())); if (isloginMain && !Accounts.main.isLogin) { await LoginUtils.onLogoutMain(); } } static Future set(AccountType key, Account account) async { await (accountMode[key]?..type.remove(key))?.onChange(); accountMode[key] = account..type.add(key); await account.onChange(); // if (!account.activited) await Request.buvidActive(account); switch (key) { case AccountType.main: await (account.isLogin ? LoginUtils.onLoginMain() : LoginUtils.onLogoutMain()); break; case AccountType.heartbeat: MineController.anonymity.value = !account.isLogin; break; default: break; } } static Account get(AccountType key) { return accountMode[key]!; } }