interconnect联网方式初步支持

This commit is contained in:
Searchstars
2024-08-27 16:36:40 +08:00
parent 379e57efb1
commit de2a4d117c
11 changed files with 268 additions and 31 deletions
+1 -1
View File
@@ -8,7 +8,7 @@
"scripts": {
"start": "aiot server --watch --open-nuttx --enable-custom-component true --enable-protobuf true",
"build": "aiot build --enable-custom-component --enable-jsc --enable-protobuf",
"release": "aiot release",
"release": "aiot release --enable-custom-component --enable-jsc --enable-protobuf",
"watch": "aiot watch --open-nuttx",
"lint": "eslint --format codeframe --fix --ext .ux,.js src/"
},
+7 -1
View File
@@ -5,16 +5,22 @@ import * as tools from "./tools"
import * as funnytips from "./funnytips"
import * as settings from "./settings"
import * as ambientlight from "./ambientlight"
import * as jumpcheck from "./jumpcheck"
import * as interconnecter from "./interconnecter"
export default {
animengine: animengine,
biliclient: new BilibiliClient(),
biliclient: null,
tools: tools,
funnytips: funnytips,
settings: settings,
ambientlight: ambientlight,
jumpcheck: jumpcheck,
interconnecter: interconnecter,
onCreate() {
console.log("app created")
settings.loadSettings()
this.biliclient = new BilibiliClient(this.settings.SETTINGS.enableInterconnectMode, this.interconnecter)
},
onDestroy() {
console.log("app destroyed")
+39 -6
View File
@@ -1,4 +1,5 @@
import { fetch, storage, crypto } from './tsimports';
import { fetch, storage, crypto, prompt } from './tsimports';
import * as interconnectfetch from './interconnectfetch'
// Wbi签名混淆表
const mixinKeyEncTab = [
@@ -24,6 +25,16 @@ class BilibiliClient {
// 版本号
public version: string = "2.2";
// Fetch API
// 会根据是否启用interconnect模式做出改变
// 具体请看constructor
public fetch: any;
// Interconnect 再封装 Message API
public interconnecter: any;
// 是否启用interconnect联网方式
private interconnect_mode: boolean;
// 扫码登录用的二维码Key
private qrCodeKey: string | null = null;
@@ -36,7 +47,7 @@ class BilibiliClient {
// B站账号信息(非AccountData
private accountInfo: any | null = null;
// 风控Cookies(不存储,登录时刷新)
// 风控Cookies(不存储,构建biliclient时更新)
private buvid3: string | null = null;
private buvid4: string | null = null;
@@ -47,6 +58,18 @@ class BilibiliClient {
return ("x" === name ? randomInt : 3 & randomInt | 8).toString(16).toUpperCase()
}));
constructor(interconnectMode = false, interconnecter = null){
this.updateBUVID();
this.interconnect_mode = interconnectMode;
if(interconnectMode){
this.fetch = new interconnectfetch.fetch(interconnecter);
this.interconnecter = interconnecter
}
else{
this.fetch = fetch;
}
}
// 获取请求头,用于模拟正常浏览器环境,降低风控概率
private getHeaders(): Record<string, string> {
return {
@@ -62,7 +85,11 @@ class BilibiliClient {
// 构建Cookie字符串
private getCookieString(): string {
return `SESSDATA=${this.sessData}; bili_jct=${this.biliJct}; DedeUserID=${this.dedeUserID}; sid=${this.sid}; buvid3=${this.buvid3}; buvid4=${this.buvid4}`;
var cookies = `buvid3=${this.buvid3}; buvid4=${this.buvid4}; `;
if(this.sessData){
cookies += `SESSDATA=${this.sessData}; bili_jct=${this.biliJct}; DedeUserID=${this.dedeUserID}; sid=${this.sid}; `
}
return cookies;
}
// Wbi签名
@@ -86,7 +113,7 @@ class BilibiliClient {
private async getRequest(url: string): Promise<any> {
console.log("getRequest: " + url);
try {
const response = await fetch.fetch({
const response = await this.fetch.fetch({
url,
responseType: 'json',
header: this.getHeaders()
@@ -114,7 +141,7 @@ class BilibiliClient {
headers = custom_headers
}
try {
const response = await fetch.fetch({
const response = await this.fetch.fetch({
url,
responseType: 'json',
method: 'POST',
@@ -138,7 +165,7 @@ class BilibiliClient {
// 检查澎湃哔哩是否存在更新
async checkHyperbilibiliUpdates(): Promise<any> {
const latestVerGet = await fetch.fetch({
const latestVerGet = await this.fetch.fetch({
url: "https://gitee.com/search__stars/hb_ota_info/raw/master/current_ver",
header: this.getHeaders()
});
@@ -159,6 +186,12 @@ class BilibiliClient {
const response = await this.getRequest('https://passport.bilibili.com/x/passport-login/web/qrcode/generate');
if (response && response.data) {
this.qrCodeKey = response.data.data.qrcode_key;
if(this.interconnect_mode){
await this.interconnecter.sendMessage(JSON.stringify({
msgtype: "SHOWQR",
message: response.data.data.url
}))
}
return { url: response.data.data.url, qrcode_key: response.data.data.qrcode_key };
} else {
throw new Error('获取二维码失败');
+87
View File
@@ -0,0 +1,87 @@
import { interconnect, prompt } from "./tsimports";
export let CONNECTION_OPEN = false;
// 生成唯一ID的工具函数
function generateUniqueId(): string {
return Math.random().toString(36).substr(2, 9);
}
interface PendingRequest {
resolve: (data: any) => void;
reject: (error: any) => void;
}
// 用于存储未完成请求的映射表
const pendingRequests: { [id: string]: PendingRequest } = {};
// 获取连接对象
const conn = interconnect.instance();
// 设置连接打开的回调
conn.onopen = () => {
console.log(`connection opened`);
setTimeout(async() => {
await sendMessage(JSON.stringify({
msgtype: "HELLO",
message: ""
}))
}, 500)
CONNECTION_OPEN = true;
};
// 设置连接关闭的回调
conn.onclose = (data) => {
console.log(`connection closed, reason = ${data.data}, code = ${data.code}`);
};
// 设置连接错误的回调
conn.onerror = (data) => {
console.log(`connection error, errMsg = ${data.data}, errCode = ${data.code}`);
};
// 处理收到消息的回调
conn.onmessage = (data) => {
const { id, response } = JSON.parse(data.data);
if (id && pendingRequests[id]) {
// 如果ID存在且匹配,则认为是对号入座的响应
pendingRequests[id].resolve(response);
// 完成请求后,删除对应的映射
delete pendingRequests[id];
} else {
console.log(`Received unrecognized message: ${data.data}`);
}
};
// 异步发送字符串并等待回应的函数
export async function sendMessage(message: string): Promise<any> {
return new Promise((resolve, reject) => {
const id = generateUniqueId();
// 将请求添加到待处理请求映射表中
pendingRequests[id] = { resolve, reject };
// 发送数据
conn.send({
data: {
id,
message,
},
success: () => {
console.log('Message sent successfully');
},
fail: (data: { data: any, code: number }) => {
prompt.showToast({
message: "interconnect通信失败:" + data.data + " 错误代码:" + data.code,
duration: 5000
})
console.log(`handling fail, errMsg = ${data.data}, errCode = ${data.code}`);
// 如果发送失败,则执行 reject
reject(new Error(`Failed to send message, errCode = ${data.code}`));
// 失败后,删除对应的映射
delete pendingRequests[id];
},
});
});
}
+23
View File
@@ -0,0 +1,23 @@
import { prompt } from "./tsimports";
export class fetch{
private interconnecter: any;
constructor(interconnecter){
this.interconnecter = interconnecter
}
async fetch(params: any){
var result = JSON.parse(await this.interconnecter.sendMessage(JSON.stringify({
msgtype: "FETCH",
message: JSON.stringify(params)
})))
if(params.responseType === "json"){
result.data = JSON.parse(result.data)
}
return {
data: result
};
}
}
+52
View File
@@ -0,0 +1,52 @@
import { storage, router, network } from './tsimports';
export async function Jump() {
storage.get({
key: "bilibili_account",
success: async (bilibili_account) => {
if (bilibili_account.length < 1) {
router.replace({
uri: "pages/login"
})
} else {
router.replace({
uri: "pages/prepage"
})
}
}
})
}
export async function GoOpenInterconnectPage() {
router.replace({
uri: "pages/interconnectguider"
})
}
export async function NetworkCheck(): Promise<boolean> {
return new Promise((resolve) => {
network.getType({
success: function (data: { type: string }) {
if (!data.type) {
console.log('Network type is empty or undefined.');
GoOpenInterconnectPage()
resolve(false);
} else if (data.type === 'none') {
resolve(false);
} else {
resolve(true);
}
},
fail: function () {
// 发生错误(如权限不足等),可以在这里处理错误逻辑
// 这里留空,供你实现具体逻辑
console.log('Failed to get network type.');
GoOpenInterconnectPage()
resolve(false);
},
complete: function () {
console.log('Network type check completed.');
}
});
});
}
+3
View File
@@ -91,6 +91,9 @@
},
"pages/donation": {
"component": "donation"
},
"pages/interconnecthelper": {
"component": "interconnecthelper"
}
}
}
@@ -0,0 +1,35 @@
<template>
<div class="page">
<text>等待连接手机</text>
</div>
</template>
<script>
export default {
private: {
checktimer: null
},
onInit(){
this.checktimer = setInterval(() => {
if(this.$app.$def.interconnecter.CONNECTION_OPEN){
this.$app.$def.jumpcheck.Jump()
}
}, 1000)
},
onDestroy(){
clearInterval(this.checktimer)
}
}
</script>
<style>
.page {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
position: absolute;
width: 100%;
}
</style>
+10 -18
View File
@@ -11,7 +11,6 @@
<script>
import router from "@system.router"
import storage from "@system.storage"
export default {
private: {
anims: {
@@ -27,22 +26,6 @@ export default {
}
}
},
async JumpCheck() {
storage.get({
key: "bilibili_account",
success: async (bilibili_account) => {
if (bilibili_account.length < 1) {
router.replace({
uri: "pages/login"
})
} else {
router.replace({
uri: "pages/prepage"
})
}
}
})
},
onShow() {
this.anims.splash = new this.$app.$def.animengine.DomAnim(
"splashPage",
@@ -64,7 +47,16 @@ export default {
setTimeout(() => {
this.anims.splash_out.start()
setTimeout(() => {
this.JumpCheck()
if(this.$app.$def.jumpcheck.NetworkCheck() || this.$app.$def.settings.SETTINGS.enableInterconnectMode){
if(this.$app.$def.settings.SETTINGS.enableInterconnectMode){
router.replace({
uri: "pages/interconnecthelper"
})
}
else{
this.$app.$def.jumpcheck.Jump()
}
}
}, 500)
}, 1000)
},
+3 -1
View File
@@ -4,12 +4,14 @@ interface SettingsInterface {
fresh_type: number;
home_vid_count: number;
enableFullAnimation: boolean;
enableInterconnectMode: boolean;
}
export let SETTINGS: SettingsInterface = {
fresh_type: 3, //视频推荐相关度,范围1-3,根据大数据推送
home_vid_count: 10,
enableFullAnimation: false
enableFullAnimation: false,
enableInterconnectMode: false
};
export function loadSettings(): void {
+8 -4
View File
@@ -1,7 +1,11 @@
import fetch from '@system.fetch';
import storage from '@system.storage';
import fetch from '@system.fetch'
import storage from '@system.storage'
import crypto from '@system.crypto'
import device from '@system.device'
import device from '@system.device'
import folme from "@system.folme"
import router from "@system.router"
import interconnect from "@system.interconnect"
import prompt from "@system.prompt"
import network from "@system.network"
export { fetch, storage, crypto, device, folme };
export { fetch, storage, crypto, device, folme, router, interconnect, prompt, network };