opt: account (#1306)

* opt: account

* opt: account

* opt: live api

* opt: buvid

* Revert "opt: buvid"

This reverts commit da1ea68f8b.

* tweak
This commit is contained in:
My-Responsitories
2025-09-23 15:58:40 +08:00
committed by GitHub
parent 6b4fb0d611
commit 1345fd36e4
18 changed files with 173 additions and 208 deletions

View File

@@ -141,7 +141,7 @@ class GrpcReq {
GeneratedMessage request, GeneratedMessage request,
T Function(Uint8List) grpcParser, T Function(Uint8List) grpcParser,
) async { ) async {
final response = await Request().post( final response = await Request().post<Uint8List>(
HttpString.appBaseUrl + url, HttpString.appBaseUrl + url,
data: compressProtobuf(request.writeToBuffer()), data: compressProtobuf(request.writeToBuffer()),
options: options, options: options,

View File

@@ -398,27 +398,6 @@ class Api {
static const String pgcUpdate = '/pgc/web/follow/status/update'; static const String pgcUpdate = '/pgc/web/follow/status/update';
// 番剧列表
// https://api.bilibili.com/pgc/season/index/result?
// st=1&
// order=3
// season_version=-1 全部-1 正片1 电影2 其他3
// spoken_language_type=-1 全部-1 原生1 中文配音2
// area=-1&
// is_finish=-1&
// copyright=-1&
// season_status=-1&
// season_month=-1&
// year=-1&
// style_id=-1&
// sort=0&
// page=1&
// season_type=1&
// pagesize=20&
// type=1
static const String pgcIndex =
'/pgc/season/index/result?st=1&order=3&season_version=-1&spoken_language_type=-1&area=-1&is_finish=-1&copyright=-1&season_status=-1&season_month=-1&year=-1&style_id=-1&sort=0&season_type=1&pagesize=20&type=1';
// 我的追番/追剧 ?type=1&pn=1&ps=15 // 我的追番/追剧 ?type=1&pn=1&ps=15
static const String favPgc = '/x/space/bangumi/follow/list'; static const String favPgc = '/x/space/bangumi/follow/list';

View File

@@ -4,6 +4,7 @@ import 'package:PiliPlus/http/init.dart';
import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/http/login.dart'; import 'package:PiliPlus/http/login.dart';
import 'package:PiliPlus/http/ua_type.dart'; import 'package:PiliPlus/http/ua_type.dart';
import 'package:PiliPlus/models/common/account_type.dart';
import 'package:PiliPlus/models/common/live_search_type.dart'; import 'package:PiliPlus/models/common/live_search_type.dart';
import 'package:PiliPlus/models_new/live/live_area_list/area_item.dart'; import 'package:PiliPlus/models_new/live/live_area_list/area_item.dart';
import 'package:PiliPlus/models_new/live/live_area_list/area_list.dart'; import 'package:PiliPlus/models_new/live/live_area_list/area_list.dart';
@@ -20,12 +21,20 @@ import 'package:PiliPlus/models_new/live/live_search/data.dart';
import 'package:PiliPlus/models_new/live/live_second_list/data.dart'; import 'package:PiliPlus/models_new/live/live_second_list/data.dart';
import 'package:PiliPlus/models_new/live/live_superchat/data.dart'; import 'package:PiliPlus/models_new/live/live_superchat/data.dart';
import 'package:PiliPlus/utils/accounts.dart'; import 'package:PiliPlus/utils/accounts.dart';
import 'package:PiliPlus/utils/accounts/account.dart';
import 'package:PiliPlus/utils/app_sign.dart'; import 'package:PiliPlus/utils/app_sign.dart';
import 'package:PiliPlus/utils/wbi_sign.dart'; import 'package:PiliPlus/utils/wbi_sign.dart';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
class LiveHttp { abstract final class LiveHttp {
static Future sendLiveMsg({roomId, msg, dmType, emoticonOptions}) async { static Account get recommend => Accounts.get(AccountType.recommend);
static Future sendLiveMsg({
required Object roomId,
required Object msg,
Object? dmType,
Object? emoticonOptions,
}) async {
String csrf = Accounts.main.csrf; String csrf = Accounts.main.csrf;
var res = await Request().post( var res = await Request().post(
Api.sendLiveMsg, Api.sendLiveMsg,
@@ -165,11 +174,10 @@ class LiveHttp {
static Future<LoadingState<LiveIndexData>> liveFeedIndex({ static Future<LoadingState<LiveIndexData>> liveFeedIndex({
required int pn, required int pn,
required bool isLogin,
bool moduleSelect = false, bool moduleSelect = false,
}) async { }) async {
final params = { final params = {
'access_key': ?Accounts.main.accessKey, 'access_key': ?recommend.accessKey,
'appkey': Constants.appKey, 'appkey': Constants.appKey,
'channel': 'master', 'channel': 'master',
'actionKey': 'appkey', 'actionKey': 'appkey',
@@ -187,7 +195,7 @@ class LiveHttp {
'network': 'wifi', 'network': 'wifi',
'page': pn, 'page': pn,
'platform': 'android', 'platform': 'android',
if (isLogin) 'relation_page': 1, if (recommend.isLogin) 'relation_page': 1,
's_locale': 'zh_CN', 's_locale': 'zh_CN',
'scale': 2, 'scale': 2,
'statistics': Constants.statisticsApp, 'statistics': Constants.statisticsApp,
@@ -245,13 +253,12 @@ class LiveHttp {
static Future<LoadingState<LiveSecondData>> liveSecondList({ static Future<LoadingState<LiveSecondData>> liveSecondList({
required int pn, required int pn,
required bool isLogin, required Object? areaId,
required areaId, required Object? parentAreaId,
required parentAreaId,
String? sortType, String? sortType,
}) async { }) async {
final params = { final params = {
'access_key': ?Accounts.main.accessKey, 'access_key': ?recommend.accessKey,
'appkey': Constants.appKey, 'appkey': Constants.appKey,
'actionKey': 'appkey', 'actionKey': 'appkey',
'channel': 'master', 'channel': 'master',
@@ -313,11 +320,9 @@ class LiveHttp {
} }
} }
static Future<LoadingState<List<AreaList>?>> liveAreaList({ static Future<LoadingState<List<AreaList>?>> liveAreaList() async {
required bool isLogin,
}) async {
final params = { final params = {
'access_key': ?Accounts.main.accessKey, 'access_key': ?recommend.accessKey,
'appkey': Constants.appKey, 'appkey': Constants.appKey,
'actionKey': 'appkey', 'actionKey': 'appkey',
'build': 8430300, 'build': 8430300,
@@ -352,9 +357,7 @@ class LiveHttp {
} }
} }
static Future<LoadingState<List<AreaItem>>> getLiveFavTag({ static Future<LoadingState<List<AreaItem>>> getLiveFavTag() async {
required bool isLogin,
}) async {
final params = { final params = {
'access_key': ?Accounts.main.accessKey, 'access_key': ?Accounts.main.accessKey,
'appkey': Constants.appKey, 'appkey': Constants.appKey,
@@ -432,11 +435,10 @@ class LiveHttp {
} }
static Future<LoadingState<List<AreaItem>?>> liveRoomAreaList({ static Future<LoadingState<List<AreaItem>?>> liveRoomAreaList({
required bool isLogin, required Object parentid,
required parentid,
}) async { }) async {
final params = { final params = {
'access_key': ?Accounts.main.accessKey, 'access_key': ?recommend.accessKey,
'appkey': Constants.appKey, 'appkey': Constants.appKey,
'actionKey': 'appkey', 'actionKey': 'appkey',
'build': 8430300, 'build': 8430300,
@@ -473,13 +475,12 @@ class LiveHttp {
} }
static Future<LoadingState<LiveSearchData>> liveSearch({ static Future<LoadingState<LiveSearchData>> liveSearch({
required bool isLogin,
required int page, required int page,
required String keyword, required String keyword,
required LiveSearchType type, required LiveSearchType type,
}) async { }) async {
final params = { final params = {
'access_key': ?Accounts.main.accessKey, 'access_key': ?recommend.accessKey,
'appkey': Constants.appKey, 'appkey': Constants.appKey,
'actionKey': 'appkey', 'actionKey': 'appkey',
'build': 8430300, 'build': 8430300,

View File

@@ -17,7 +17,7 @@ import 'package:encrypt/encrypt.dart';
class LoginHttp { class LoginHttp {
static final String deviceId = LoginUtils.genDeviceId(); static final String deviceId = LoginUtils.genDeviceId();
static final String buvid = LoginUtils.buvid; static String get buvid => LoginUtils.buvid;
static final Map<String, String> headers = { static final Map<String, String> headers = {
'buvid': buvid, 'buvid': buvid,
'env': 'prod', 'env': 'prod',

View File

@@ -62,8 +62,23 @@ class PgcHttp {
int? indexType, int? indexType,
}) async { }) async {
var res = await Request().get( var res = await Request().get(
Api.pgcIndex, Api.pgcIndexResult,
queryParameters: { queryParameters: {
'st': 1,
'order': 3,
'season_version': -1,
'spoken_language_type': -1,
'area': -1,
'is_finish': -1,
'copyright': -1,
'season_status': -1,
'season_month': -1,
'year': -1,
'style_id': -1,
'sort': 0,
'season_type': 1,
'pagesize': 20,
'type': 1,
'page': page, 'page': page,
'index_type': ?indexType, 'index_type': ?indexType,
}, },

View File

@@ -13,7 +13,7 @@ import 'package:dio/dio.dart';
class ReplyHttp { class ReplyHttp {
static final Options options = Options( static final Options options = Options(
headers: {...Constants.baseHeaders, 'cookie': ''}, headers: {...Constants.baseHeaders, 'cookie': ''},
extra: {'account': NoAccount()}, extra: {'account': const NoAccount()},
); );
static Future<LoadingState> replyList({ static Future<LoadingState> replyList({

View File

@@ -7,7 +7,6 @@ import 'package:PiliPlus/models_new/live/live_feed_index/data.dart';
import 'package:PiliPlus/models_new/live/live_second_list/data.dart'; import 'package:PiliPlus/models_new/live/live_second_list/data.dart';
import 'package:PiliPlus/models_new/live/live_second_list/tag.dart'; import 'package:PiliPlus/models_new/live/live_second_list/tag.dart';
import 'package:PiliPlus/pages/common/common_list_controller.dart'; import 'package:PiliPlus/pages/common/common_list_controller.dart';
import 'package:PiliPlus/services/account_service.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
class LiveController extends CommonListController { class LiveController extends CommonListController {
@@ -17,8 +16,6 @@ class LiveController extends CommonListController {
queryData(); queryData();
} }
AccountService accountService = Get.find<AccountService>();
int? count; int? count;
// area // area
@@ -75,16 +72,12 @@ class LiveController extends CommonListController {
if (areaIndex.value != 0) { if (areaIndex.value != 0) {
return LiveHttp.liveSecondList( return LiveHttp.liveSecondList(
pn: page, pn: page,
isLogin: accountService.isLogin.value,
areaId: areaId, areaId: areaId,
parentAreaId: parentAreaId, parentAreaId: parentAreaId,
sortType: sortType, sortType: sortType,
); );
} }
return LiveHttp.liveFeedIndex( return LiveHttp.liveFeedIndex(pn: page);
pn: page,
isLogin: accountService.isLogin.value,
);
} }
@override @override
@@ -99,11 +92,7 @@ class LiveController extends CommonListController {
} }
Future<void> queryTop() async { Future<void> queryTop() async {
final res = await LiveHttp.liveFeedIndex( final res = await LiveHttp.liveFeedIndex(pn: page, moduleSelect: true);
pn: page,
isLogin: accountService.isLogin.value,
moduleSelect: true,
);
if (res.isSuccess) { if (res.isSuccess) {
final data = res.data; final data = res.data;
topState.value = Pair( topState.value = Pair(

View File

@@ -36,12 +36,10 @@ class LiveAreaController
@override @override
Future<LoadingState<List<AreaList>?>> customGetData() => Future<LoadingState<List<AreaList>?>> customGetData() =>
LiveHttp.liveAreaList(isLogin: accountService.isLogin.value); LiveHttp.liveAreaList();
Future<void> queryFavTags() async { Future<void> queryFavTags() async {
favState.value = await LiveHttp.getLiveFavTag( favState.value = await LiveHttp.getLiveFavTag();
isLogin: accountService.isLogin.value,
);
} }
Future<void> setFavTag() async { Future<void> setFavTag() async {

View File

@@ -6,7 +6,6 @@ import 'package:PiliPlus/models_new/live/live_feed_index/card_data_list_item.dar
import 'package:PiliPlus/models_new/live/live_second_list/data.dart'; import 'package:PiliPlus/models_new/live/live_second_list/data.dart';
import 'package:PiliPlus/models_new/live/live_second_list/tag.dart'; import 'package:PiliPlus/models_new/live/live_second_list/tag.dart';
import 'package:PiliPlus/pages/common/common_list_controller.dart'; import 'package:PiliPlus/pages/common/common_list_controller.dart';
import 'package:PiliPlus/services/account_service.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
class LiveAreaChildController class LiveAreaChildController
@@ -23,8 +22,6 @@ class LiveAreaChildController
final RxInt tagIndex = 0.obs; final RxInt tagIndex = 0.obs;
List<LiveSecondTag>? newTags; List<LiveSecondTag>? newTags;
AccountService accountService = Get.find<AccountService>();
@override @override
void onInit() { void onInit() {
super.onInit(); super.onInit();
@@ -53,7 +50,6 @@ class LiveAreaChildController
Future<LoadingState<LiveSecondData>> customGetData() => Future<LoadingState<LiveSecondData>> customGetData() =>
LiveHttp.liveSecondList( LiveHttp.liveSecondList(
pn: page, pn: page,
isLogin: accountService.isLogin.value,
areaId: areaId, areaId: areaId,
parentAreaId: parentAreaId, parentAreaId: parentAreaId,
sortType: sortType, sortType: sortType,

View File

@@ -4,8 +4,6 @@ import 'package:PiliPlus/http/live.dart';
import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models_new/live/live_area_list/area_item.dart'; import 'package:PiliPlus/models_new/live/live_area_list/area_item.dart';
import 'package:PiliPlus/pages/common/common_list_controller.dart'; import 'package:PiliPlus/pages/common/common_list_controller.dart';
import 'package:PiliPlus/services/account_service.dart';
import 'package:get/get.dart';
class LiveAreaDatailController class LiveAreaDatailController
extends CommonListController<List<AreaItem>?, AreaItem> { extends CommonListController<List<AreaItem>?, AreaItem> {
@@ -15,8 +13,6 @@ class LiveAreaDatailController
late int initialIndex = 0; late int initialIndex = 0;
AccountService accountService = Get.find<AccountService>();
@override @override
void onInit() { void onInit() {
super.onInit(); super.onInit();
@@ -33,8 +29,5 @@ class LiveAreaDatailController
@override @override
Future<LoadingState<List<AreaItem>?>> customGetData() => Future<LoadingState<List<AreaItem>?>> customGetData() =>
LiveHttp.liveRoomAreaList( LiveHttp.liveRoomAreaList(parentid: parentAreaId);
isLogin: accountService.isLogin.value,
parentid: parentAreaId,
);
} }

View File

@@ -4,8 +4,6 @@ import 'package:PiliPlus/models/common/live_search_type.dart';
import 'package:PiliPlus/models_new/live/live_search/data.dart'; import 'package:PiliPlus/models_new/live/live_search/data.dart';
import 'package:PiliPlus/pages/common/common_list_controller.dart'; import 'package:PiliPlus/pages/common/common_list_controller.dart';
import 'package:PiliPlus/pages/live_search/controller.dart'; import 'package:PiliPlus/pages/live_search/controller.dart';
import 'package:PiliPlus/services/account_service.dart';
import 'package:get/get.dart';
class LiveSearchChildController class LiveSearchChildController
extends CommonListController<LiveSearchData, dynamic> { extends CommonListController<LiveSearchData, dynamic> {
@@ -14,8 +12,6 @@ class LiveSearchChildController
final LiveSearchController controller; final LiveSearchController controller;
final LiveSearchType searchType; final LiveSearchType searchType;
AccountService accountService = Get.find<AccountService>();
@override @override
void checkIsEnd(int length) { void checkIsEnd(int length) {
switch (searchType) { switch (searchType) {
@@ -48,7 +44,6 @@ class LiveSearchChildController
@override @override
Future<LoadingState<LiveSearchData>> customGetData() { Future<LoadingState<LiveSearchData>> customGetData() {
return LiveHttp.liveSearch( return LiveHttp.liveSearch(
isLogin: accountService.isLogin.value,
page: page, page: page,
keyword: controller.editingController.text, keyword: controller.editingController.text,
type: searchType, type: searchType,

View File

@@ -690,7 +690,11 @@ class LoginPageController extends GetxController
tokenInfo['refresh_token'], tokenInfo['refresh_token'],
); );
await Future.wait([account.onChange(), AnonymousAccount().delete()]); await Future.wait([account.onChange(), AnonymousAccount().delete()]);
Accounts.accountMode.updateAll((_, a) => a == account ? account : a); for (int i = 0; i < AccountType.values.length; i++) {
if (Accounts.accountMode[i].mid == account.mid) {
Accounts.accountMode[i] = account;
}
}
if (Accounts.main.isLogin) { if (Accounts.main.isLogin) {
SmartDialog.showToast('登录成功'); SmartDialog.showToast('登录成功');
} else { } else {
@@ -704,7 +708,7 @@ class LoginPageController extends GetxController
SmartDialog.showToast('请先登录'); SmartDialog.showToast('请先登录');
return Get.toNamed('/loginPage'); return Get.toNamed('/loginPage');
} }
final selectAccount = Map.of(Accounts.accountMode); final selectAccount = List.of(Accounts.accountMode);
final options = { final options = {
AnonymousAccount(): '0', AnonymousAccount(): '0',
...Accounts.account.toMap().map( ...Accounts.account.toMap().map(
@@ -729,9 +733,9 @@ class LoginPageController extends GetxController
.map( .map(
(e) => Builder( (e) => Builder(
builder: (context) => RadioGroup( builder: (context) => RadioGroup(
groupValue: selectAccount[e], groupValue: selectAccount[e.index],
onChanged: (v) { onChanged: (v) {
selectAccount[e] = v!; selectAccount[e.index] = v!;
(context as Element).markNeedsBuild(); (context as Element).markNeedsBuild();
}, },
child: WrapRadioOptionsGroup<Account>( child: WrapRadioOptionsGroup<Account>(
@@ -756,9 +760,9 @@ class LoginPageController extends GetxController
), ),
TextButton( TextButton(
onPressed: () { onPressed: () {
for (var i in selectAccount.entries) { for (var (i, v) in selectAccount.indexed) {
if (i.value != Accounts.get(i.key)) { if (v != Accounts.accountMode[i]) {
Accounts.set(i.key, i.value); Accounts.set(AccountType.values[i], v);
} }
} }
Get.back(); Get.back();

View File

@@ -229,7 +229,8 @@ class MineController
} }
res == true res == true
? Accounts.set(AccountType.heartbeat, AnonymousAccount()) ? Accounts.set(AccountType.heartbeat, AnonymousAccount())
: Accounts.accountMode[AccountType.heartbeat] = AnonymousAccount(); : Accounts.accountMode[AccountType.heartbeat.index] =
AnonymousAccount();
}); });
} else { } else {
Accounts.set(AccountType.heartbeat, Accounts.main); Accounts.set(AccountType.heartbeat, Accounts.main);

View File

@@ -41,11 +41,9 @@ List<SettingsModel> get privacySettings => [
context: Get.context!, context: Get.context!,
builder: (context) { builder: (context) {
return AlertDialog( return AlertDialog(
title: const Text('查看详情'), title: const Text('账号模式详情'),
content: SingleChildScrollView( content: SingleChildScrollView(
child: Text( child: _getAccountDetail(context),
AccountManager.apiTypeSet[AccountType.heartbeat]!.join('\n'),
),
), ),
actions: [ actions: [
TextButton( TextButton(
@@ -58,7 +56,26 @@ List<SettingsModel> get privacySettings => [
); );
}, },
leading: const Icon(Icons.flag_outlined), leading: const Icon(Icons.flag_outlined),
title: '了解无痕模式', title: '了解账号模式',
subtitle: '查看无痕模式作用的API列表', subtitle: '查看各个账号模式作用的API列表',
), ),
]; ];
Widget _getAccountDetail(BuildContext context) {
final slivers = <Widget>[];
final theme = TextTheme.of(context);
for (var i in AccountType.values) {
final url = AccountManager.apiTypeSet[i];
if (url == null) continue;
slivers
..add(Center(child: Text(i.title, style: theme.titleMedium)))
..add(SelectableText(url.join('\n')));
}
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 8,
children: slivers,
);
}

View File

@@ -7,9 +7,12 @@ import 'package:hive/hive.dart';
abstract class Accounts { abstract class Accounts {
static late final Box<LoginAccount> account; static late final Box<LoginAccount> account;
static final Map<AccountType, Account> accountMode = {}; static final List<Account> accountMode = List.filled(
static Account get main => accountMode[AccountType.main]!; AccountType.values.length,
static Account get heartbeat => accountMode[AccountType.heartbeat]!; AnonymousAccount(),
);
static Account get main => accountMode[AccountType.main.index];
static Account get heartbeat => accountMode[AccountType.heartbeat.index];
static Account get history { static Account get history {
final heartbeat = Accounts.heartbeat; final heartbeat = Accounts.heartbeat;
if (heartbeat is AnonymousAccount) { if (heartbeat is AnonymousAccount) {
@@ -70,14 +73,11 @@ abstract class Accounts {
static Future<void> refresh() async { static Future<void> refresh() async {
for (var a in account.values) { for (var a in account.values) {
for (var t in a.type) { for (var t in a.type) {
accountMode[t] = a; accountMode[t.index] = a;
} }
} }
for (var type in AccountType.values) {
accountMode[type] ??= AnonymousAccount();
}
await Future.wait( await Future.wait(
(accountMode.values.toSet()..retainWhere((i) => !i.activited)).map( (accountMode.toSet()..removeWhere((i) => i.activited)).map(
Request.buvidActive, Request.buvidActive,
), ),
); );
@@ -85,7 +85,7 @@ abstract class Accounts {
static Future<void> clear() async { static Future<void> clear() async {
await account.clear(); await account.clear();
for (var i in AccountType.values) { for (int i = 0; i < AccountType.values.length; i++) {
accountMode[i] = AnonymousAccount(); accountMode[i] = AnonymousAccount();
} }
await AnonymousAccount().delete(); await AnonymousAccount().delete();
@@ -100,9 +100,11 @@ abstract class Accounts {
static Future<void> deleteAll(Set<Account> accounts) async { static Future<void> deleteAll(Set<Account> accounts) async {
var isloginMain = Accounts.main.isLogin; var isloginMain = Accounts.main.isLogin;
Accounts.accountMode.updateAll( for (int i = 0; i < AccountType.values.length; i++) {
(_, a) => accounts.contains(a) ? AnonymousAccount() : a, if (accounts.contains(accountMode[i])) {
); accountMode[i] = AnonymousAccount();
}
}
await Future.wait(accounts.map((i) => i.delete())); await Future.wait(accounts.map((i) => i.delete()));
if (isloginMain && !Accounts.main.isLogin) { if (isloginMain && !Accounts.main.isLogin) {
await LoginUtils.onLogoutMain(); await LoginUtils.onLogoutMain();
@@ -110,8 +112,8 @@ abstract class Accounts {
} }
static Future<void> set(AccountType key, Account account) async { static Future<void> set(AccountType key, Account account) async {
await (accountMode[key]?..type.remove(key))?.onChange(); await (accountMode[key.index]..type.remove(key)).onChange();
accountMode[key] = account..type.add(key); accountMode[key.index] = account..type.add(key);
await account.onChange(); await account.onChange();
if (!account.activited) await Request.buvidActive(account); if (!account.activited) await Request.buvidActive(account);
switch (key) { switch (key) {
@@ -129,6 +131,6 @@ abstract class Accounts {
} }
static Account get(AccountType key) { static Account get(AccountType key) {
return accountMode[key]!; return accountMode[key.index];
} }
} }

View File

@@ -5,41 +5,52 @@ import 'package:PiliPlus/utils/id_utils.dart';
import 'package:cookie_jar/cookie_jar.dart'; import 'package:cookie_jar/cookie_jar.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
abstract class Account { sealed class Account {
final bool isLogin = false; Map<String, dynamic>? toJson() => null;
late final DefaultCookieJar cookieJar;
String? accessKey;
String? refresh;
late final Set<AccountType> type;
final int mid = 0; Future<void> onChange() => Future.value();
late String csrf;
final Map<String, String> headers = const {};
bool activited = false; Set<AccountType> get type => const {};
Future<void> delete(); bool get activited => false;
Future<void> onChange();
Map<String, dynamic>? toJson(); set activited(bool value) => throw UnimplementedError();
String? get accessKey => throw UnimplementedError();
DefaultCookieJar get cookieJar => throw UnimplementedError();
String get csrf => throw UnimplementedError();
Future<void> delete() => throw UnimplementedError();
Map<String, String> get headers => throw UnimplementedError();
bool get isLogin => throw UnimplementedError();
int get mid => throw UnimplementedError();
String? get refresh => throw UnimplementedError();
const Account();
} }
@HiveType(typeId: 9) @HiveType(typeId: 9)
class LoginAccount implements Account { class LoginAccount extends Account {
@override @override
final bool isLogin = true; final bool isLogin = true;
@override @override
@HiveField(0) @HiveField(0)
late final DefaultCookieJar cookieJar; final DefaultCookieJar cookieJar;
@override @override
@HiveField(1) @HiveField(1)
String? accessKey; final String? accessKey;
@override @override
@HiveField(2) @HiveField(2)
String? refresh; final String? refresh;
@override @override
@HiveField(3) @HiveField(3)
late final Set<AccountType> type; final Set<AccountType> type;
@override @override
bool activited = false; bool activited = false;
@@ -55,14 +66,22 @@ class LoginAccount implements Account {
}; };
@override @override
late String csrf = late final String csrf =
cookieJar.domainCookies['bilibili.com']!['/']!['bili_jct']!.cookie.value; cookieJar.domainCookies['bilibili.com']!['/']!['bili_jct']!.cookie.value;
@override bool _hasDelete = false;
Future<void> delete() => _box.delete(_midStr);
@override @override
Future<void> onChange() => _box.put(_midStr, this); Future<void> delete() {
assert(_hasDelete = true);
return _box.delete(_midStr);
}
@override
Future<void> onChange() {
assert(!_hasDelete);
return _box.put(_midStr, this);
}
@override @override
Map<String, dynamic>? toJson() => { Map<String, dynamic>? toJson() => {
@@ -88,16 +107,12 @@ class LoginAccount implements Account {
cookieJar.setBuvid3(); cookieJar.setBuvid3();
} }
LoginAccount.fromJson(Map json) { factory LoginAccount.fromJson(Map json) => LoginAccount(
cookieJar = BiliCookieJar.fromJson(json['cookies'])..setBuvid3(); BiliCookieJar.fromJson(json['cookies']),
accessKey = json['accessKey']; json['accessKey'],
refresh = json['refresh']; json['refresh'],
type = (json['type'] as Iterable?)?.map((i) => AccountType.values[i]).toSet(),
(json['type'] as Iterable?) );
?.map((i) => AccountType.values[i])
.toSet() ??
{};
}
@override @override
int get hashCode => mid.hashCode; int get hashCode => mid.hashCode;
@@ -107,21 +122,21 @@ class LoginAccount implements Account {
identical(this, other) || (other is LoginAccount && mid == other.mid); identical(this, other) || (other is LoginAccount && mid == other.mid);
} }
class AnonymousAccount implements Account { class AnonymousAccount extends Account {
@override @override
final bool isLogin = false; final bool isLogin = false;
@override @override
late final DefaultCookieJar cookieJar; final DefaultCookieJar cookieJar = DefaultCookieJar()..setBuvid3();
@override @override
String? accessKey; final String? accessKey = null;
@override @override
String? refresh; final String? refresh = null;
@override @override
Set<AccountType> type = {}; final Set<AccountType> type = {};
@override @override
final int mid = 0; final int mid = 0;
@override @override
String csrf = ''; final String csrf = '';
@override @override
final Map<String, String> headers = Constants.baseHeaders; final Map<String, String> headers = Constants.baseHeaders;
@@ -134,17 +149,9 @@ class AnonymousAccount implements Account {
cookieJar.setBuvid3(); cookieJar.setBuvid3();
} }
@override
Future<void> onChange() async {}
@override
Map<String, dynamic>? toJson() => null;
static final _instance = AnonymousAccount._(); static final _instance = AnonymousAccount._();
AnonymousAccount._() { AnonymousAccount._();
cookieJar = DefaultCookieJar(ignoreExpires: true)..setBuvid3();
}
factory AnonymousAccount() => _instance; factory AnonymousAccount() => _instance;
@@ -179,8 +186,9 @@ extension BiliCookieJar on DefaultCookieJar {
[]; [];
void setBuvid3() { void setBuvid3() {
domainCookies['bilibili.com'] ??= {'/': {}}; (domainCookies['bilibili.com'] ??= {
domainCookies['bilibili.com']!['/']!['buvid3'] ??= SerializableCookie( '/': {},
})['/']!['buvid3'] ??= SerializableCookie(
Cookie('buvid3', IdUtils.genBuvid3())..setBiliDomain(), Cookie('buvid3', IdUtils.genBuvid3())..setBiliDomain(),
); );
} }
@@ -208,52 +216,6 @@ extension BiliCookieJar on DefaultCookieJar {
}; };
} }
class NoAccount implements Account { final class NoAccount extends Account {
@override const NoAccount();
String? accessKey;
@override
bool activited = false;
@override
DefaultCookieJar cookieJar = DefaultCookieJar();
@override
String csrf = '';
@override
String? refresh;
@override
Set<AccountType> type = const {};
@override
Future<void> delete() {
return Future.value();
}
@override
final Map<String, String> headers = const {};
@override
bool isLogin = false;
@override
int mid = 0;
@override
Future<void> onChange() {
return Future.value();
}
@override
Map<String, dynamic>? toJson() {
return null;
}
NoAccount._();
static final _instance = NoAccount._();
factory NoAccount() => _instance;
} }

View File

@@ -51,6 +51,7 @@ class AccountManager extends Interceptor {
Api.getSeasonDetailApi, Api.getSeasonDetailApi,
Api.liveRoomDmToken, Api.liveRoomDmToken,
Api.liveRoomDmPrefetch, Api.liveRoomDmPrefetch,
Api.superChatMsg,
Api.searchByType, Api.searchByType,
Api.dynSearch, Api.dynSearch,
Api.searchArchive, Api.searchArchive,
@@ -68,6 +69,18 @@ class AccountManager extends Interceptor {
Api.liveList, Api.liveList,
Api.searchTrending, Api.searchTrending,
Api.searchRecommend, Api.searchRecommend,
Api.getRankApi,
Api.pgcRank,
Api.pgcSeasonRank,
Api.pgcIndexResult,
Api.popularSeriesOne,
Api.popularSeriesList,
Api.popularPrecious,
Api.liveAreaList,
Api.liveFeedIndex,
Api.liveSecondList,
Api.liveRoomAreaList,
Api.liveSearch,
}, },
// progress // progress
AccountType.video: { AccountType.video: {
@@ -118,7 +131,7 @@ class AccountManager extends Interceptor {
late final Account account = options.extra['account'] ?? _findAccount(path); late final Account account = options.extra['account'] ?? _findAccount(path);
if (_skipCookie(path) || account is NoAccount) return handler.next(options); if (account is NoAccount || _skipCookie(path)) return handler.next(options);
if (!account.isLogin && path == Api.heartBeat) { if (!account.isLogin && path == Api.heartBeat) {
return handler.reject( return handler.reject(

View File

@@ -25,7 +25,7 @@ abstract class Update {
Api.latestApp, Api.latestApp,
options: Options( options: Options(
headers: {'user-agent': UaType.mob.ua}, headers: {'user-agent': UaType.mob.ua},
extra: {'account': NoAccount()}, extra: {'account': const NoAccount()},
), ),
); );
if (res.data is Map || res.data.isEmpty) { if (res.data is Map || res.data.isEmpty) {