mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-21 09:50:13 +08:00
opt: buvid
This commit is contained in:
@@ -13,7 +13,6 @@ import 'package:PiliPlus/http/init.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/utils/accounts.dart';
|
||||
import 'package:PiliPlus/utils/id_utils.dart';
|
||||
import 'package:PiliPlus/utils/login_utils.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:archive/archive.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
@@ -21,35 +20,46 @@ import 'package:flutter/foundation.dart' show kDebugMode;
|
||||
import 'package:protobuf/protobuf.dart' show GeneratedMessage;
|
||||
|
||||
class GrpcReq {
|
||||
static String? _accessKey = Accounts.main.accessKey;
|
||||
static const _build = 2001100;
|
||||
static const _versionName = '2.0.1';
|
||||
static const _biliChannel = 'master';
|
||||
static const _mobiApp = 'android_hd';
|
||||
static const _device = 'android';
|
||||
|
||||
static final _buvid = LoginUtils.buvid;
|
||||
static final _traceId = IdUtils.genTraceId();
|
||||
static final _sessionId = Utils.generateRandomString(8);
|
||||
|
||||
static void updateHeaders(String? accessKey) {
|
||||
_accessKey = accessKey;
|
||||
if (_accessKey != null) {
|
||||
headers['authorization'] = 'identify_v1 $_accessKey';
|
||||
static void updateHeaders(String? accessKey, String buvid) {
|
||||
if (accessKey != null) {
|
||||
headers['authorization'] = 'identify_v1 $accessKey';
|
||||
} else {
|
||||
headers.remove('authorization');
|
||||
}
|
||||
headers['x-bili-metadata-bin'] = base64Encode(
|
||||
Metadata(
|
||||
accessKey: _accessKey ?? '',
|
||||
accessKey: accessKey ?? '',
|
||||
mobiApp: _mobiApp,
|
||||
device: _device,
|
||||
build: _build,
|
||||
channel: _biliChannel,
|
||||
buvid: _buvid,
|
||||
buvid: buvid,
|
||||
platform: _device,
|
||||
).writeToBuffer(),
|
||||
);
|
||||
headers['x-bili-device-bin'] = base64Encode(
|
||||
Device(
|
||||
appId: 5,
|
||||
build: _build,
|
||||
buvid: buvid,
|
||||
mobiApp: _mobiApp,
|
||||
platform: _device,
|
||||
channel: _biliChannel,
|
||||
brand: _device,
|
||||
model: _device,
|
||||
osver: '15',
|
||||
versionName: _versionName,
|
||||
).writeToBuffer(),
|
||||
);
|
||||
options = Options(headers: headers, responseType: ResponseType.bytes);
|
||||
}
|
||||
|
||||
@@ -61,8 +71,9 @@ class GrpcReq {
|
||||
'x-bili-gaia-vtoken': '',
|
||||
'x-bili-aurora-zone': '',
|
||||
'x-bili-trace-id': _traceId,
|
||||
if (_accessKey != null) 'authorization': 'identify_v1 $_accessKey',
|
||||
'buvid': _buvid,
|
||||
if (Accounts.main.accessKey != null)
|
||||
'authorization': 'identify_v1 ${Accounts.main.accessKey}',
|
||||
'buvid': Accounts.main.buvid,
|
||||
'bili-http-engine': 'cronet',
|
||||
'te': 'trailers',
|
||||
'x-bili-fawkes-req-bin': base64Encode(
|
||||
@@ -74,12 +85,12 @@ class GrpcReq {
|
||||
),
|
||||
'x-bili-metadata-bin': base64Encode(
|
||||
Metadata(
|
||||
accessKey: _accessKey ?? '',
|
||||
accessKey: Accounts.main.accessKey ?? '',
|
||||
mobiApp: _mobiApp,
|
||||
device: _device,
|
||||
build: _build,
|
||||
channel: _biliChannel,
|
||||
buvid: _buvid,
|
||||
buvid: Accounts.main.buvid,
|
||||
platform: _device,
|
||||
).writeToBuffer(),
|
||||
),
|
||||
@@ -87,7 +98,7 @@ class GrpcReq {
|
||||
Device(
|
||||
appId: 5,
|
||||
build: _build,
|
||||
buvid: _buvid,
|
||||
buvid: Accounts.main.buvid,
|
||||
mobiApp: _mobiApp,
|
||||
platform: _device,
|
||||
channel: _biliChannel,
|
||||
@@ -141,7 +152,7 @@ class GrpcReq {
|
||||
GeneratedMessage request,
|
||||
T Function(Uint8List) grpcParser,
|
||||
) async {
|
||||
final response = await Request().post(
|
||||
final response = await Request().post<Uint8List>(
|
||||
HttpString.appBaseUrl + url,
|
||||
data: compressProtobuf(request.writeToBuffer()),
|
||||
options: options,
|
||||
|
||||
@@ -2,7 +2,6 @@ import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/http/api.dart';
|
||||
import 'package:PiliPlus/http/init.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/http/login.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';
|
||||
@@ -211,7 +210,7 @@ abstract final class LiveHttp {
|
||||
queryParameters: params,
|
||||
options: Options(
|
||||
headers: {
|
||||
'buvid': LoginHttp.buvid,
|
||||
'buvid': recommend.buvid,
|
||||
'fp_local':
|
||||
'1111111111111111111111111111111111111111111111111111111111111111',
|
||||
'fp_remote':
|
||||
@@ -297,7 +296,7 @@ abstract final class LiveHttp {
|
||||
queryParameters: params,
|
||||
options: Options(
|
||||
headers: {
|
||||
'buvid': LoginHttp.buvid,
|
||||
'buvid': recommend.buvid,
|
||||
'fp_local':
|
||||
'1111111111111111111111111111111111111111111111111111111111111111',
|
||||
'fp_remote':
|
||||
|
||||
@@ -17,9 +17,9 @@ import 'package:encrypt/encrypt.dart';
|
||||
|
||||
class LoginHttp {
|
||||
static final String deviceId = LoginUtils.genDeviceId();
|
||||
static String get buvid => LoginUtils.buvid;
|
||||
static String get _buvid => AnonymousAccount().buvid;
|
||||
static final Map<String, String> headers = {
|
||||
'buvid': buvid,
|
||||
'buvid': _buvid,
|
||||
'env': 'prod',
|
||||
'app-key': 'android_hd',
|
||||
'user-agent': Constants.userAgent,
|
||||
@@ -99,7 +99,7 @@ class LoginHttp {
|
||||
int timestamp = DateTime.now().millisecondsSinceEpoch;
|
||||
var data = {
|
||||
'build': '2001100',
|
||||
'buvid': buvid,
|
||||
'buvid': _buvid,
|
||||
'c_locale': 'zh_CN',
|
||||
'channel': 'master',
|
||||
'cid': cid,
|
||||
@@ -108,10 +108,10 @@ class LoginHttp {
|
||||
'gee_challenge': ?geeChallenge,
|
||||
'gee_seccode': ?geeSeccode,
|
||||
'gee_validate': ?geeValidate,
|
||||
'local_id': buvid,
|
||||
'local_id': _buvid,
|
||||
// https://chinggg.github.io/post/appre/
|
||||
'login_session_id': md5
|
||||
.convert(utf8.encode(buvid + timestamp.toString()))
|
||||
.convert(utf8.encode(_buvid + timestamp.toString()))
|
||||
.toString(),
|
||||
'mobi_app': 'android_hd',
|
||||
'platform': 'android',
|
||||
@@ -202,7 +202,7 @@ class LoginHttp {
|
||||
Map<String, String> data = {
|
||||
'bili_local_id': deviceId,
|
||||
'build': '2001100',
|
||||
'buvid': buvid,
|
||||
'buvid': _buvid,
|
||||
'c_locale': 'zh_CN',
|
||||
'channel': 'master',
|
||||
'device': 'phone',
|
||||
@@ -221,7 +221,7 @@ class LoginHttp {
|
||||
'gee_challenge': ?geeChallenge,
|
||||
'gee_seccode': ?geeSeccode,
|
||||
'gee_validate': ?geeValidate,
|
||||
'local_id': buvid, //LoginUtils.generateBuvid(),
|
||||
'local_id': _buvid, //LoginUtils.generateBuvid(),
|
||||
'mobi_app': 'android_hd',
|
||||
'password': passwordEncrypted,
|
||||
'permission': 'ALL',
|
||||
@@ -271,7 +271,7 @@ class LoginHttp {
|
||||
Map<String, String> data = {
|
||||
'bili_local_id': deviceId,
|
||||
'build': '2001100',
|
||||
'buvid': buvid,
|
||||
'buvid': _buvid,
|
||||
'c_locale': 'zh_CN',
|
||||
'captcha_key': captchaKey,
|
||||
'channel': 'master',
|
||||
@@ -291,7 +291,7 @@ class LoginHttp {
|
||||
),
|
||||
'from_pv': 'main.my-information.my-login.0.click',
|
||||
'from_url': Uri.encodeComponent('bilibili://user_center/mine'),
|
||||
'local_id': buvid,
|
||||
'local_id': _buvid,
|
||||
'mobi_app': 'android_hd',
|
||||
'platform': 'android',
|
||||
's_locale': 'zh_CN',
|
||||
@@ -452,7 +452,7 @@ class LoginHttp {
|
||||
Map<String, String> data = {
|
||||
'appkey': Constants.appKey,
|
||||
'build': '2001100',
|
||||
'buvid': buvid,
|
||||
'buvid': _buvid,
|
||||
// 'c_locale': 'zh_CN',
|
||||
// 'channel': 'master',
|
||||
'code': code,
|
||||
@@ -462,7 +462,7 @@ class LoginHttp {
|
||||
// 'device_platform': 'Android14vivo',
|
||||
'disable_rcmd': '0',
|
||||
'grant_type': 'authorization_code',
|
||||
'local_id': buvid,
|
||||
'local_id': _buvid,
|
||||
'mobi_app': 'android_hd',
|
||||
'platform': 'android',
|
||||
// 's_locale': 'zh_CN',
|
||||
@@ -505,7 +505,7 @@ class LoginHttp {
|
||||
|
||||
static Future<LoadingState<LoginDevicesData>> loginDevices() async {
|
||||
final account = Accounts.main;
|
||||
final buvid = LoginUtils.buvid;
|
||||
final buvid = account.buvid;
|
||||
final params = {
|
||||
'local_id': buvid,
|
||||
'buvid': buvid,
|
||||
|
||||
@@ -4,7 +4,6 @@ import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/http/api.dart';
|
||||
import 'package:PiliPlus/http/init.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/http/login.dart';
|
||||
import 'package:PiliPlus/http/ua_type.dart';
|
||||
import 'package:PiliPlus/models/common/account_type.dart';
|
||||
import 'package:PiliPlus/models/common/video/video_type.dart';
|
||||
@@ -112,7 +111,7 @@ class VideoHttp {
|
||||
queryParameters: params,
|
||||
options: Options(
|
||||
headers: {
|
||||
'buvid': LoginHttp.buvid,
|
||||
'buvid': Accounts.get(AccountType.recommend).buvid,
|
||||
'fp_local':
|
||||
'1111111111111111111111111111111111111111111111111111111111111111',
|
||||
'fp_remote':
|
||||
|
||||
@@ -688,6 +688,8 @@ class LoginPageController extends GetxController
|
||||
BiliCookieJar.fromList(cookieInfo),
|
||||
tokenInfo['access_token'],
|
||||
tokenInfo['refresh_token'],
|
||||
{},
|
||||
AnonymousAccount().buvid,
|
||||
);
|
||||
await Future.wait([account.onChange(), AnonymousAccount().delete()]);
|
||||
for (int i = 0; i < AccountType.values.length; i++) {
|
||||
|
||||
@@ -41,11 +41,9 @@ List<SettingsModel> get privacySettings => [
|
||||
context: Get.context!,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: const Text('查看详情'),
|
||||
title: const Text('账号模式详情'),
|
||||
content: SingleChildScrollView(
|
||||
child: Text(
|
||||
AccountManager.apiTypeSet[AccountType.heartbeat]!.join('\n'),
|
||||
),
|
||||
child: _getAccountDetail(context),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
@@ -58,7 +56,26 @@ List<SettingsModel> get privacySettings => [
|
||||
);
|
||||
},
|
||||
leading: const Icon(Icons.flag_outlined),
|
||||
title: '了解无痕模式',
|
||||
subtitle: '查看无痕模式作用的API列表',
|
||||
title: '了解账号模式',
|
||||
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,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/models/common/account_type.dart';
|
||||
import 'package:PiliPlus/utils/accounts.dart';
|
||||
import 'package:PiliPlus/utils/id_utils.dart';
|
||||
import 'package:PiliPlus/utils/login_utils.dart';
|
||||
import 'package:cookie_jar/cookie_jar.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
@@ -32,6 +33,8 @@ sealed class Account {
|
||||
|
||||
String? get refresh => throw UnimplementedError();
|
||||
|
||||
String get buvid => throw UnimplementedError();
|
||||
|
||||
const Account();
|
||||
}
|
||||
|
||||
@@ -51,6 +54,9 @@ class LoginAccount extends Account {
|
||||
@override
|
||||
@HiveField(3)
|
||||
final Set<AccountType> type;
|
||||
@override
|
||||
@HiveField(4)
|
||||
final String buvid;
|
||||
|
||||
@override
|
||||
bool activited = false;
|
||||
@@ -69,11 +75,19 @@ class LoginAccount extends Account {
|
||||
late final String csrf =
|
||||
cookieJar.domainCookies['bilibili.com']!['/']!['bili_jct']!.cookie.value;
|
||||
|
||||
@override
|
||||
Future<void> delete() => _box.delete(_midStr);
|
||||
bool _hasDelete = false;
|
||||
|
||||
@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
|
||||
Map<String, dynamic>? toJson() => {
|
||||
@@ -81,6 +95,7 @@ class LoginAccount extends Account {
|
||||
'accessKey': accessKey,
|
||||
'refresh': refresh,
|
||||
'type': type.map((i) => i.index).toList(),
|
||||
'buvid': buvid,
|
||||
};
|
||||
|
||||
late final String _midStr = cookieJar
|
||||
@@ -95,7 +110,9 @@ class LoginAccount extends Account {
|
||||
this.accessKey,
|
||||
this.refresh, [
|
||||
Set<AccountType>? type,
|
||||
]) : type = type ?? {} {
|
||||
String? buvid,
|
||||
]) : type = type ?? {},
|
||||
buvid = buvid ?? LoginUtils.generateBuvid() {
|
||||
cookieJar.setBuvid3();
|
||||
}
|
||||
|
||||
@@ -104,6 +121,7 @@ class LoginAccount extends Account {
|
||||
json['accessKey'],
|
||||
json['refresh'],
|
||||
(json['type'] as Iterable?)?.map((i) => AccountType.values[i]).toSet(),
|
||||
json['buvid'],
|
||||
);
|
||||
|
||||
@override
|
||||
@@ -131,12 +149,15 @@ class AnonymousAccount extends Account {
|
||||
final String csrf = '';
|
||||
@override
|
||||
final Map<String, String> headers = Constants.baseHeaders;
|
||||
@override
|
||||
String buvid = LoginUtils.generateBuvid();
|
||||
|
||||
@override
|
||||
bool activited = false;
|
||||
|
||||
@override
|
||||
Future<void> delete() async {
|
||||
buvid = LoginUtils.generateBuvid();
|
||||
await cookieJar.deleteAll();
|
||||
cookieJar.setBuvid3();
|
||||
}
|
||||
|
||||
@@ -18,13 +18,14 @@ class LoginAccountAdapter extends TypeAdapter<LoginAccount> {
|
||||
fields[1] as String?,
|
||||
fields[2] as String?,
|
||||
(fields[3] as List?)?.cast<AccountType>().toSet(),
|
||||
fields[4] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, LoginAccount obj) {
|
||||
writer
|
||||
..writeByte(4)
|
||||
..writeByte(5)
|
||||
..writeByte(0)
|
||||
..write(obj.cookieJar)
|
||||
..writeByte(1)
|
||||
@@ -32,7 +33,9 @@ class LoginAccountAdapter extends TypeAdapter<LoginAccount> {
|
||||
..writeByte(2)
|
||||
..write(obj.refresh)
|
||||
..writeByte(3)
|
||||
..write(obj.type.toList());
|
||||
..write(obj.type.toList())
|
||||
..writeByte(4)
|
||||
..write(obj.buvid);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -49,11 +49,12 @@ abstract class LoginUtils {
|
||||
|
||||
static Future<void> onLoginMain() async {
|
||||
final account = Accounts.main;
|
||||
GrpcReq.updateHeaders(account.accessKey);
|
||||
setWebCookie(account);
|
||||
RequestUtils.syncHistoryStatus();
|
||||
final result = await UserHttp.userInfo();
|
||||
if (result.isSuccess) {
|
||||
GrpcReq.updateHeaders(account.accessKey, account.buvid);
|
||||
setWebCookie(account);
|
||||
RequestUtils.syncHistoryStatus();
|
||||
|
||||
final UserInfoData data = result.data;
|
||||
if (data.isLogin == true) {
|
||||
Get.find<AccountService>()
|
||||
@@ -114,7 +115,7 @@ abstract class LoginUtils {
|
||||
..face.value = ''
|
||||
..isLogin.value = false;
|
||||
|
||||
GrpcReq.updateHeaders(null);
|
||||
GrpcReq.updateHeaders(null, AnonymousAccount().buvid);
|
||||
|
||||
await Future.wait([
|
||||
if (!Platform.isWindows) web.CookieManager.instance().deleteAllCookies(),
|
||||
@@ -166,8 +167,6 @@ abstract class LoginUtils {
|
||||
return 'XY${md5Str[2]}${md5Str[12]}${md5Str[22]}$md5Str';
|
||||
}
|
||||
|
||||
static final buvid = Pref.buvid;
|
||||
|
||||
// static String getUUID() {
|
||||
// return const Uuid().v4().replaceAll('-', '');
|
||||
// }
|
||||
|
||||
@@ -221,8 +221,7 @@ abstract class LocalCacheKey {
|
||||
blackMids = 'blackMids',
|
||||
danmakuFilterRules = 'danmakuFilterRules',
|
||||
mixinKey = 'mixinKey',
|
||||
timeStamp = 'timeStamp',
|
||||
buvid = 'buvid';
|
||||
timeStamp = 'timeStamp';
|
||||
}
|
||||
|
||||
abstract class VideoBoxKey {
|
||||
|
||||
@@ -26,7 +26,6 @@ import 'package:PiliPlus/plugin/pl_player/models/play_repeat.dart';
|
||||
import 'package:PiliPlus/utils/context_ext.dart';
|
||||
import 'package:PiliPlus/utils/extension.dart';
|
||||
import 'package:PiliPlus/utils/global_data.dart';
|
||||
import 'package:PiliPlus/utils/login_utils.dart';
|
||||
import 'package:PiliPlus/utils/storage.dart';
|
||||
import 'package:PiliPlus/utils/storage_key.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -801,15 +800,6 @@ abstract class Pref {
|
||||
static bool get silentDownImg =>
|
||||
_setting.get(SettingBoxKey.silentDownImg, defaultValue: false);
|
||||
|
||||
static String get buvid {
|
||||
String? buvid = _localCache.get(LocalCacheKey.buvid);
|
||||
if (buvid == null) {
|
||||
buvid = LoginUtils.generateBuvid();
|
||||
_localCache.put(LocalCacheKey.buvid, buvid);
|
||||
}
|
||||
return buvid;
|
||||
}
|
||||
|
||||
static bool get showMemberShop =>
|
||||
_setting.get(SettingBoxKey.showMemberShop, defaultValue: false);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user